-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# -* Makefile *-
# Author : Patrick GOLDBRONN (CEA)
# Date : 28/06/2001
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPLUGIN_version.h
// Author : Vadim SANDLER
// Module : SALOME
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
include $(top_srcdir)/adm_local/unix/make_common_starter.am
SUBDIRS = unix
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_occ})
SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_opti})
SET(NETGEN_LIBS ${NETGEN_LIBS} ${NETGEN_LIB_stlgeom})
+
+SET(CMAKE_BUILD 1)
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
include $(top_srcdir)/adm_local/unix/make_common_starter.am
SUBDIRS = config_files
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
include $(top_srcdir)/adm_local/unix/make_common_starter.am
dist_admlocalm4_DATA = \
-dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2010 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 See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
dnl
+
AC_DEFUN([CHECK_NETGEN],[
AC_REQUIRE([AC_PROG_CXX])dnl
if test "x$Netgen_ok" == xno ; then
AC_MSG_RESULT(no)
- AC_MSG_ERROR(Netgen is not properly installed)
+ AC_MSG_ERROR(Netgen is not properly installed. Read NETGENPLUGIN_SRC/src/NETGEN/ReadMeForNgUsers for details.)
fi
NETGEN_LIBS="-L${NETGEN_LIBS_DIR} -lnglib"
if test "x$Netgen_ok" == xno ; then
AC_MSG_RESULT(no)
- AC_MSG_WARN(Netgen libraries not found or not properly installed)
+ AC_MSG_ERROR(Netgen libraries not found or not properly installed)
else
AC_MSG_RESULT(yes)
fi
+
+else
+
+ AC_MSG_ERROR(Netgen libraries not found. Please define NETGENHOME or use --with-netgen option)
+
fi
AC_SUBST(NETGEN_INCLUDES)
-dnl Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+dnl Copyright (C) 2007-2010 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 See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
dnl
+
#------------------------------------------------------------
# Check availability of Salome NETGEN mesh plugin module
# distribution
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# The following is to avoid PACKAGE_... env variable
# redefinition compilation warnings
# ============================================================
+#
AM_CXXFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h
AM_CPPFLAGS = @KERNEL_CXXFLAGS@ -include SALOMEconfig.h
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# -* Makefile *-
# Author : Guillaume Boulant (CSSI)
# Module : KERNEL
#!/bin/sh
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
-\r
+@REM Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
+@REM
+@REM This library is free software; you can redistribute it and/or
+@REM modify it under the terms of the GNU Lesser General Public
+@REM License as published by the Free Software Foundation; either
+@REM version 2.1 of the License.
+@REM
+@REM This library is distributed in the hope that it will be useful,
+@REM but WITHOUT ANY WARRANTY; without even the implied warranty of
+@REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+@REM Lesser General Public License for more details.
+@REM
+@REM You should have received a copy of the GNU Lesser General Public
+@REM License along with this library; if not, write to the Free Software
+@REM Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+@REM
+@REM See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+@REM
+
%PYTHONBIN% %KERNEL_ROOT_DIR%\salome_adm\cmake_files\am2cmake.py --netgenplugin\r
#!/bin/bash
-# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+# 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
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# Tool for updating list of .in file for the SALOME project
# and regenerating configure script
# Author : Marc Tajchman - CEA
#!/bin/sh
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
rm -rf autom4te.cache aclocal.m4 configure make_config
find . -name "*~" -print -exec rm {} \;
find . -name "*.pyc" -print -exec rm {} \;
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# PLEASE DO NOT MODIFY configure.in FILE
# ALL CHANGES WILL BE DISCARDED BY THE NEXT
# build_configure COMMAND
# Reorganization for usage of autotools
# Created from configure.in.base
#
-AC_INIT([Salome2 Project NETGENPLUGIN module], [5.1.3], [webmaster.salome@opencascade.com], [SalomeNETGENPLUGIN])
+AC_INIT([Salome2 Project NETGENPLUGIN module], [5.1.4], [webmaster.salome@opencascade.com], [SalomeNETGENPLUGIN])
AC_CONFIG_AUX_DIR(adm_local/unix/config_files)
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
echo ---------------------------------------------
echo
+AM_CONDITIONAL(CMAKE_BUILD, 0)
#AM_CONDITIONAL( USE_GFORTRAN, [test "$F77" = "gfortran"])
echo Configure
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# This Makefile is responsible of generating the client and server
# implementation of IDL interfaces for both C++ and python usage.
# The building process of the C++ files is in charge of each source
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPlugin_Algorithm.idl
// Author : Julia DOROVSKIKH
// $Header$
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# -* Makefile *-
# Author : Patrick GOLDBRONN (CEA)
# Date : 28/06/2001
<?xml version='1.0' encoding='us-ascii'?>
<!DOCTYPE meshers PUBLIC "" "desktop.dtd">
<!--
- Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+ 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
<!--
- Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+ 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
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# File : Makefile.in
# Author : Michael Sazonov
# Modified by : Alexander BORODIN (OCN) - autotools usage
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin
// File : NETGENPluginGUI.cxx
// Author : Michael Zorin
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin
// File : NETGENPluginGUI.h
// Author : Alexander A. BORODIN
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin
// File : NETGENPluginGUI_HypothesisCreator.cxx
// Author : Michael Zorin
#include <SMESHGUI_Utils.h>
#include <SMESHGUI_HypothesesUtils.h>
#include <SMESHGUI.h>
+#include <SMESHGUI_SpinBox.h>
#include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm)
#include <SalomeApp_Tools.h>
-#include <SalomeApp_DoubleSpinBox.h>
-
#include <QComboBox>
#include <QLabel>
#include <QGroupBox>
}
aGroupLayout->addWidget( new QLabel( tr( "NETGEN_MAX_SIZE" ), GroupC1 ), row, 0 );
- myMaxSize = new SalomeApp_DoubleSpinBox( GroupC1 );
- myMaxSize->setDecimals( 7 );
- myMaxSize->setMinimum( 1e-07 );
- myMaxSize->setMaximum( 1e+06 );
- myMaxSize->setSingleStep( 10 );
+ myMaxSize = new SMESHGUI_SpinBox( GroupC1 );
+ myMaxSize->RangeStepAndValidator( 1e-07, 1e+06, 10., "length_precision" );
aGroupLayout->addWidget( myMaxSize, row, 1 );
row++;
row++;
aGroupLayout->addWidget( new QLabel( tr( "NETGEN_GROWTH_RATE" ), GroupC1 ), row, 0 );
- myGrowthRate = new SalomeApp_DoubleSpinBox( GroupC1 );
- myGrowthRate->setMinimum( 0.1 );
- myGrowthRate->setMaximum( 10 );
- myGrowthRate->setSingleStep( 0.1 );
+ myGrowthRate = new SMESHGUI_SpinBox( GroupC1 );
+ myGrowthRate->RangeStepAndValidator( .1, 10., .1, "parametric_precision" );
aGroupLayout->addWidget( myGrowthRate, row, 1 );
row++;
const double VALUE_MAX = 1.0e+6;
aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_EDGE" ), GroupC1 ), row, 0 );
- myNbSegPerEdge = new SalomeApp_DoubleSpinBox( GroupC1 );
- myNbSegPerEdge->setMinimum( 0.2 );
- myNbSegPerEdge->setMaximum( VALUE_MAX ); // (PAL14890) max value in native netgen gui is 5
+ myNbSegPerEdge = new SMESHGUI_SpinBox( GroupC1 );
+ myNbSegPerEdge->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" );
aGroupLayout->addWidget( myNbSegPerEdge, row, 1 );
row++;
aGroupLayout->addWidget( new QLabel( tr( "NETGEN_SEG_PER_RADIUS" ), GroupC1 ), row, 0 );
- myNbSegPerRadius = new SalomeApp_DoubleSpinBox( GroupC1 );
- myNbSegPerRadius->setMinimum( 0.2 );
- myNbSegPerRadius->setMaximum( VALUE_MAX ); // (PAL14890) max value in native netgen gui is 5
+ myNbSegPerRadius = new SMESHGUI_SpinBox( GroupC1 );
+ myNbSegPerRadius->RangeStepAndValidator( .2, VALUE_MAX, .1, "parametric_precision" );
aGroupLayout->addWidget( myNbSegPerRadius, row, 1 );
row++;
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin GUI: GUI for plugged-in mesher NETGENPlugin
// File : NETGENPluginGUI_HypothesisCreator.h
// Author : Michael Zorin
#include <SMESHGUI_Hypotheses.h>
-class SalomeApp_DoubleSpinBox;
+class SMESHGUI_SpinBox;
class QComboBox;
class QCheckBox;
class QLineEdit;
private:
QLineEdit* myName;
- SalomeApp_DoubleSpinBox* myMaxSize;
+ SMESHGUI_SpinBox* myMaxSize;
QCheckBox* mySecondOrder;
QCheckBox* myOptimize;
QComboBox* myFineness;
- SalomeApp_DoubleSpinBox* myGrowthRate;
- SalomeApp_DoubleSpinBox* myNbSegPerEdge;
- SalomeApp_DoubleSpinBox* myNbSegPerRadius;
+ SMESHGUI_SpinBox* myGrowthRate;
+ SMESHGUI_SpinBox* myNbSegPerEdge;
+ SMESHGUI_SpinBox* myNbSegPerRadius;
QCheckBox* myAllowQuadrangles;
bool myIs2D;
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPluginGUI_SimpleCreator.cxx
// Author : Open CASCADE S.A.S.
// SMESH includes
// * local length
myLengthRadioBut = new QRadioButton( tr( "SMESH_LOCAL_LENGTH_HYPOTHESIS" ), dimGroup );
myLength = new SMESHGUI_SpinBox( dimGroup );
- myLength->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 0.1, 6 );
+ myLength->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 0.1, "length_precision" );
myLength->setValue( 1. );
dimLay->addWidget( myLengthRadioBut, dimRow, 0 );
dimLay->addWidget( myLength, dimRow, 1 );
// * max area
dimLay->addWidget( new QLabel( tr( "SMESH_MAX_ELEMENT_AREA_HYPOTHESIS" ), dimGroup), dimRow, 0);
myArea = new SMESHGUI_SpinBox( dimGroup );
- myArea->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 0.1, 6 );
+ myArea->RangeStepAndValidator( VALUE_SMALL_2, VALUE_MAX_2, 0.1, "area_precision" );
myArea->setValue( 1. );
dimLay->addWidget( myArea, dimRow, 1 );
dimRow++;
// * max volume
dimLay->addWidget(new QLabel( tr("SMESH_MAX_ELEMENT_VOLUME_HYPOTHESIS"), dimGroup), dimRow, 0);
myVolume = new SMESHGUI_SpinBox( dimGroup );
- myVolume->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 0.1, 6 );
+ myVolume->RangeStepAndValidator( VALUE_SMALL_3, VALUE_MAX_3, 0.1, "volume_precision" );
myVolume->setValue( 1. );
dimLay->addWidget( myVolume, dimRow, 1 );
dimRow++;
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPluginGUI_SimpleCreator.h
// Author : Open CASCADE S.A.S.
//
<!DOCTYPE TS>
<!--
- Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+ 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
<!DOCTYPE TS>
<!--
- Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+ 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
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# File : Makefile.in
# Author : Patrick GOLDBRONN (CEA)
# Modified by : Alexander BORODIN (OCN) - autotools usage
include $(top_srcdir)/adm_local/unix/make_common_starter.am
SUBDIRS =
-if ! NETGEN_NEW
+if CMAKE_BUILD
+else
+if NETGEN_NEW
+else
SUBDIRS += NETGEN
endif
+endif
SUBDIRS += NETGENPlugin
if NETGENPLUGIN_ENABLE_GUI
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# -* Makefile *-
# Author : Edward AGAPOV (OCC)
# Modified by : Alexander BORODIN (OCN) - autotools usage
1. How to build Netgen for Netgen Plugin
------------------------------
-1.1. Download Netgen archive (here netgen-4.9.11.tar.gz) and unpack it
+1.1. Download Netgen archive (here netgen-4.9.12.tar.gz) and unpack it
1.2. Configure the netgen compilation. The "good" options are
- ../netgen-4.9.11/configure \
+ ../netgen-4.9.12/configure \
--prefix=THE_INSTALLATION_PATH \
- --enable-occ --enable-nglib --with-occ=${CASROOT} \
- CXXFLAGS="-DOCCGEOMETRY -I${CASROOT}/inc -DHAVE_IOSTREAM -DHAVE_LIMITS -DHAVE_LIMITS_H -DHAVE_IOMANIP -I${TOGL_HOME}/include" \
+ --with-occ=${CASROOT} \
+ CXXFLAGS="-I${TOGL_HOME}/include" \
LDFLAGS="-L${TOGL_HOME}/lib/Togl1.7"
1.3. Compile the netgen product
-# 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
+# Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
#
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
#
+
# -* Makefile *-
# Author : Edward AGAPOV (OCC)
# Modified by : Alexander BORODIN (OCN) - autotools usage
libNETGENEngine_la_LDFLAGS += \
../../idl/libSalomeIDLNETGENPLUGIN.la \
$(CAS_LDPATH) -lTKernel -lTKBRep -lTKShHealing -lTKSTEP -lTKXSBase -lTKIGES -lTKMesh -lTKSTL -lTKG3d -lTKTopAlgo -lTKG2d -lTKBool -lTKGeomAlgo -lTKOffset -lTKGeomBase -lTKBO \
+ $(MED_LDFLAGS) -lSalomeIDLMED \
$(SMESH_LDFLAGS) -lSMESHimpl -lSMESHEngine -lStdMeshersEngine -lStdMeshers -lSMESHDS -lSMDS -lSMESHControls \
$(KERNEL_LDFLAGS) -lSalomeGenericObj -lSALOMELocalTrace -lOpUtil
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
//=============================================================================
// File : NETGENPlugin_Defs.hxx
// Author : Alexander A. BORODIN
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_2D.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_2D.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_2D_i.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_2D_i.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_i.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Hypothesis_i.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Mesher.cxx
// Author : Michael Sazonov (OCN)
#include "NETGENPlugin_Hypothesis_2D.hxx"
#include "NETGENPlugin_SimpleHypothesis_3D.hxx"
-#include <SMESH_Mesh.hxx>
+#include <SMDS_FaceOfNodes.hxx>
+#include <SMDS_MeshElement.hxx>
+#include <SMDS_MeshNode.hxx>
+#include <SMESHDS_Mesh.hxx>
#include <SMESH_Comment.hxx>
#include <SMESH_ComputeError.hxx>
-#include <SMESH_subMesh.hxx>
+#include <SMESH_File.hxx>
+#include <SMESH_Mesh.hxx>
#include <SMESH_MesherHelper.hxx>
-#include <SMESHDS_Mesh.hxx>
-#include <SMDS_MeshElement.hxx>
-#include <SMDS_MeshNode.hxx>
+#include <SMESH_subMesh.hxx>
#include <utilities.h>
#include <vector>
#include <TopoDS.hxx>
// Netgen include files
-namespace nglib {
-#include <nglib.h>
-}
#define OCCGEOMETRY
#include <occgeom.hpp>
#include <meshing.hpp>
extern MeshingParameters mparam;
}
+using namespace nglib;
using namespace std;
#ifdef _DEBUG_
-#define nodeVec_ACCESS(index) nodeVec.at((index))
+#define nodeVec_ACCESS(index) (SMDS_MeshNode*) nodeVec.at((index))
#else
-#define nodeVec_ACCESS(index) nodeVec[index]
+#define nodeVec_ACCESS(index) (SMDS_MeshNode*) nodeVec[index]
#endif
+#ifdef NETGEN_NEW
+#define NGPOINT_COORDS(p) p(0),p(1),p(2)
+#else
+#define NGPOINT_COORDS(p) p.X(),p.Y(),p.Z()
+#endif
+
+// dump elements added to ng mesh
+//#define DUMP_SEGMENTS
+//#define DUMP_TRIANGLES
+//#define DUMP_TRIANGLES_SCRIPT "/tmp/trias.py" //!< debug addIntVerticesInSolids()
+
//=============================================================================
/*!
*
void NETGENPlugin_Mesher::defaultParameters()
{
-#ifdef WNT
- netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters();
-#else
netgen::MeshingParameters& mparams = netgen::mparam;
-#endif
// maximal mesh edge size
mparams.maxh = NETGENPlugin_Hypothesis::GetDefaultMaxSize();
// minimal number of segments per edge
{
if (hyp)
{
-#ifdef WNT
- netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters();
-#else
netgen::MeshingParameters& mparams = netgen::mparam;
-#endif
// Initialize global NETGEN parameters:
// maximal mesh segment size
mparams.maxh = hyp->GetMaxSize();
*/
//================================================================================
-void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo,
- const TopoDS_Shape& shape,
- SMESH_Mesh& mesh,
- list< SMESH_subMesh* > * meshedSM,
- TopTools_DataMapOfShapeShape* internalE2F)
+void NETGENPlugin_Mesher::PrepareOCCgeometry(netgen::OCCGeometry& occgeo,
+ const TopoDS_Shape& shape,
+ SMESH_Mesh& mesh,
+ list< SMESH_subMesh* > * meshedSM,
+ NETGENPlugin_Internals* intern)
{
BRepTools::Clean (shape);
try {
occgeo.shape = shape;
occgeo.changed = 1;
- //occgeo.BuildFMap();
-
- TopTools_MapOfShape internalV;
- if ( internalE2F )
- {
- for ( TopExp_Explorer f( shape, TopAbs_FACE ); f.More(); f.Next() )
- for ( TopExp_Explorer e( f.Current(), TopAbs_EDGE ); e.More(); e.Next() )
- if ( e.Current().Orientation() == TopAbs_INTERNAL )
- {
- SMESH_subMesh* sm = mesh.GetSubMesh( e.Current() );
- if ( !meshedSM || sm->IsEmpty() ) {
- internalE2F->Bind( e.Current(), f.Current() );
- for ( TopoDS_Iterator v(e.Current()); v.More(); v.Next() )
- internalV.Add( v.Value() );
- }
- }
- }
// fill maps of shapes of occgeo with not yet meshed subshapes
// to find a right orientation of subshapes (PAL20462)
TopTools_IndexedMapOfShape subShapes;
TopExp::MapShapes(root->GetSubShape(), subShapes);
- while ( smIt->more() ) {
+ while ( smIt->more() )
+ {
SMESH_subMesh* sm = smIt->next();
- if ( !meshedSM || sm->IsEmpty() ) {
- TopoDS_Shape shape = sm->GetSubShape();
+ TopoDS_Shape shape = sm->GetSubShape();
+ if ( intern && intern->isShapeToPrecompute( shape ))
+ continue;
+ if ( !meshedSM || sm->IsEmpty() )
+ {
if ( shape.ShapeType() != TopAbs_VERTEX )
shape = subShapes( subShapes.FindIndex( shape ));// shape -> index -> oriented shape
+ if ( shape.Orientation() >= TopAbs_INTERNAL )
+ shape.Orientation( TopAbs_FORWARD ); // isuue 0020676
switch ( shape.ShapeType() ) {
case TopAbs_FACE : occgeo.fmap.Add( shape ); break;
- case TopAbs_EDGE :
- if ( !internalE2F || !internalE2F->IsBound( shape )) occgeo.emap.Add( shape ); break;
- case TopAbs_VERTEX:
- if ( !internalV.Contains( shape )) occgeo.vmap.Add( shape ); break;
+ case TopAbs_EDGE : occgeo.emap.Add( shape ); break;
+ case TopAbs_VERTEX: occgeo.vmap.Add( shape ); break;
case TopAbs_SOLID :occgeo.somap.Add( shape ); break;
default:;
}
}
// collect submeshes of meshed shapes
- else if (meshedSM) {
+ else if (meshedSM)
+ {
meshedSM->push_back( sm );
}
}
#ifdef NETGEN_NEW
occgeo.face_maxh.SetSize(occgeo.fmap.Extent());
occgeo.face_maxh = netgen::mparam.maxh;
+ occgeo.face_maxh_modified.SetSize(occgeo.fmap.Extent());
+ occgeo.face_maxh_modified = 0;
#endif
}
-//================================================================================
-/*!
- * \brief return id of netgen point corresponding to SMDS node
- */
-//================================================================================
-typedef map< const SMDS_MeshNode*, int > TNode2IdMap;
-
-static int ngNodeId( const SMDS_MeshNode* node,
- netgen::Mesh& ngMesh,
- TNode2IdMap& nodeNgIdMap)
+namespace
{
- int newNgId = ngMesh.GetNP() + 1;
+ //================================================================================
+ /*!
+ * \brief return id of netgen point corresponding to SMDS node
+ */
+ //================================================================================
+ typedef map< const SMDS_MeshNode*, int > TNode2IdMap;
+
+ int ngNodeId( const SMDS_MeshNode* node,
+ netgen::Mesh& ngMesh,
+ TNode2IdMap& nodeNgIdMap)
+ {
+ int newNgId = ngMesh.GetNP() + 1;
- pair< TNode2IdMap::iterator, bool > it_isNew = nodeNgIdMap.insert( make_pair( node, newNgId ));
+ TNode2IdMap::iterator node_id = nodeNgIdMap.insert( make_pair( node, newNgId )).first;
- if ( it_isNew.second ) {
- netgen::MeshPoint p( netgen::Point<3> (node->X(), node->Y(), node->Z()) );
- ngMesh.AddPoint( p );
+ if ( node_id->second == newNgId)
+ {
+#if defined(DUMP_SEGMENTS) || defined(DUMP_TRIANGLES)
+ cout << "Ng " << newNgId << " - " << node;
+#endif
+ netgen::MeshPoint p( netgen::Point<3> (node->X(), node->Y(), node->Z()) );
+ ngMesh.AddPoint( p );
+ }
+ return node_id->second;
}
- return it_isNew.first->second;
}
//================================================================================
*/
//================================================================================
-bool NETGENPlugin_Mesher::fillNgMesh(netgen::OCCGeometry& occgeom,
+bool NETGENPlugin_Mesher::fillNgMesh(const netgen::OCCGeometry& occgeom,
netgen::Mesh& ngMesh,
- vector<SMDS_MeshNode*>& nodeVec,
+ vector<const SMDS_MeshNode*>& nodeVec,
const list< SMESH_subMesh* > & meshedSM)
{
TNode2IdMap nodeNgIdMap;
+ if ( !nodeVec.empty() )
+ for ( int i = 1; i < nodeVec.size(); ++i )
+ nodeNgIdMap.insert( make_pair( nodeVec[i], i ));
TopTools_MapOfShape visitedShapes;
SMESH_MesherHelper helper (*_mesh);
int faceID = occgeom.fmap.Extent();
- _faceDescriptors.clear();
list< SMESH_subMesh* >::const_iterator smIt, smEnd = meshedSM.end();
for ( smIt = meshedSM.begin(); smIt != smEnd; ++smIt )
continue;
SMESHDS_SubMesh * smDS = sm->GetSubMeshDS();
+ if ( !smDS ) continue;
switch ( sm->GetSubShape().ShapeType() )
{
case TopAbs_EDGE: { // EDGE
// ----------------------
- const TopoDS_Edge& geomEdge = TopoDS::Edge( sm->GetSubShape() );
+ TopoDS_Edge geomEdge = TopoDS::Edge( sm->GetSubShape() );
+ if ( geomEdge.Orientation() >= TopAbs_INTERNAL )
+ geomEdge.Orientation( TopAbs_FORWARD ); // isuue 0020676
// Add ng segments for each not meshed face the edge bounds
TopTools_MapOfShape visitedAncestors;
- const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomEdge );
- TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
- for ( ; ancestorIt.More(); ancestorIt.Next() )
+ PShapeIteratorPtr fIt = helper.GetAncestors( geomEdge, *sm->GetFather(), TopAbs_FACE );
+ while ( const TopoDS_Shape * anc = fIt->next() )
{
- const TopoDS_Shape & ans = ancestorIt.Value();
- if ( ans.ShapeType() != TopAbs_FACE || !visitedAncestors.Add( ans ))
- continue;
- const TopoDS_Face& face = TopoDS::Face( ans );
+ if ( !visitedAncestors.Add( *anc )) continue;
+ TopoDS_Face face = TopoDS::Face( *anc );
+ if ( face.Orientation() >= TopAbs_INTERNAL )
+ face.Orientation( TopAbs_FORWARD ); // isuue 0020676
int faceID = occgeom.fmap.FindIndex( face );
if ( faceID < 1 )
continue; // meshed face
// find out orientation of geomEdge within face
- TopAbs_Orientation fOri;
- for ( TopExp_Explorer exp( face, TopAbs_EDGE ); exp.More(); exp.Next() ) {
- if ( geomEdge.IsSame( exp.Current() )) {
- fOri = exp.Current().Orientation();
- break;
- }
- }
+ TopAbs_Orientation fOri = helper.GetSubShapeOri( face, geomEdge );
// get all nodes from geomEdge
bool isForwad = ( fOri == geomEdge.Orientation() );
netgen::Segment seg;
// ng node ids
-#ifdef NETGEN_NEW
- seg.pnums[0] = prevNgId;
- seg.pnums[1] = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap );
-#else
- seg.p1 = prevNgId;
- seg.p2 = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap );
-#endif
+ seg[0] = prevNgId;
+ seg[1] = prevNgId = ngNodeId( p2.node, ngMesh, nodeNgIdMap );
// node param on curve
seg.epgeominfo[ 0 ].dist = p1.param;
seg.epgeominfo[ 1 ].dist = p2.param;
seg.si = faceID; // = geom.fmap.FindIndex (face);
seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
ngMesh.AddSegment (seg);
-
+#ifdef DUMP_SEGMENTS
+ cout << "Segment: " << seg.edgenr << " on SMESH face " << helper.GetMeshDS()->ShapeToIndex( face ) << endl
+ << "\tface index: " << seg.si << endl
+ << "\tp1: " << seg.p1 << endl
+ << "\tp2: " << seg.p2 << endl
+ << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl
+ << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl
+ << "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl
+ << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl
+ << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl
+ << "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl;
+#endif
if ( isSeam )
{
if ( helper.GetPeriodicIndex() == 1 ) {
seg.epgeominfo[ 1 ].v = otherSeamParam;
swap (seg.epgeominfo[0].u, seg.epgeominfo[1].u);
}
-#ifdef NETGEN_NEW
- swap (seg.pnums[0], seg.pnums[1]);
-#else
- swap (seg.p1, seg.p2);
-#endif
+ swap (seg[0], seg[1]);
swap (seg.epgeominfo[0].dist, seg.epgeominfo[1].dist);
seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
ngMesh.AddSegment (seg);
}
else if ( fOri == TopAbs_INTERNAL )
{
-#ifdef NETGEN_NEW
- swap (seg.pnums[0], seg.pnums[1]);
-#else
- swap (seg.p1, seg.p2);
-#endif
+ swap (seg[0], seg[1]);
swap( seg.epgeominfo[0], seg.epgeominfo[1] );
seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
ngMesh.AddSegment (seg);
+#ifdef DUMP_SEGMENTS
+ cout << "Segment: " << seg.edgenr << endl << "\t is REVERSE of the previous" << endl;
+#endif
}
}
} // loop on geomEdge ancestors
// ----------------------
const TopoDS_Face& geomFace = TopoDS::Face( sm->GetSubShape() );
helper.SetSubShape( geomFace );
+ bool isInternalFace = ( geomFace.Orientation() == TopAbs_INTERNAL );
// Find solids the geomFace bounds
int solidID1 = 0, solidID2 = 0;
- const TopTools_ListOfShape& ancestors = _mesh->GetAncestors( geomFace );
- TopTools_ListIteratorOfListOfShape ancestorIt ( ancestors );
- for ( ; ancestorIt.More(); ancestorIt.Next() )
+ PShapeIteratorPtr solidIt = helper.GetAncestors( geomFace, *sm->GetFather(), TopAbs_SOLID);
+ while ( const TopoDS_Shape * solid = solidIt->next() )
{
- const TopoDS_Shape & solid = ancestorIt.Value();
- if ( solid.ShapeType() == TopAbs_SOLID ) {
- int id = occgeom.somap.FindIndex ( solid );
- if ( solidID1 && id != solidID1 ) solidID2 = id;
- else solidID1 = id;
- }
+ int id = occgeom.somap.FindIndex ( *solid );
+ if ( solidID1 && id != solidID1 ) solidID2 = id;
+ else solidID1 = id;
}
faceID++;
_faceDescriptors[ faceID ].first = solidID1;
bool reverse = false;
if ( solidID1 ) {
TopoDS_Shape solid = occgeom.somap( solidID1 );
- for ( TopExp_Explorer f( solid, TopAbs_FACE ); f.More(); f.Next() ) {
- if ( geomFace.IsSame( f.Current() )) {
- reverse = SMESH_Algo::IsReversedSubMesh( TopoDS::Face( f.Current()), helper.GetMeshDS() );
- break;
- }
- }
+ TopAbs_Orientation faceOriInSolid = helper.GetSubShapeOri( solid, geomFace );
+ if ( faceOriInSolid >= 0 )
+ reverse = SMESH_Algo::IsReversedSubMesh
+ ( TopoDS::Face( geomFace.Oriented( faceOriInSolid )), helper.GetMeshDS() );
}
// Add surface elements
- SMDS_ElemIteratorPtr faces = smDS->GetElements();
- while ( faces->more() ) {
+ netgen::Element2d tri(3);
+ tri.SetIndex ( faceID );
+
+
+#ifdef DUMP_TRIANGLES
+ cout << "SMESH face " << helper.GetMeshDS()->ShapeToIndex( geomFace )
+ << " internal="<<isInternalFace<< " border="<<isBorderFace << endl;
+#endif
+ SMDS_ElemIteratorPtr faces = smDS->GetElements();
+ while ( faces->more() )
+ {
const SMDS_MeshElement* f = faces->next();
- if ( f->NbNodes() % 3 != 0 ) { // not triangle
- for ( ancestorIt.Initialize(ancestors); ancestorIt.More(); ancestorIt.Next() )
- if ( ancestorIt.Value().ShapeType() == TopAbs_SOLID ) {
- sm = _mesh->GetSubMesh( ancestorIt.Value() );
- break;
- }
+ if ( f->NbNodes() % 3 != 0 ) // not triangle
+ {
+ PShapeIteratorPtr solidIt=helper.GetAncestors(geomFace,*sm->GetFather(),TopAbs_SOLID);
+ if ( const TopoDS_Shape * solid = solidIt->next() )
+ sm = _mesh->GetSubMesh( *solid );
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
smError.reset( new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,"Not triangle submesh"));
smError->myBadElements.push_back( f );
return false;
}
- netgen::Element2d tri(3);
- tri.SetIndex ( faceID );
-
- for ( int i = 0; i < 3; ++i ) {
+ for ( int i = 0; i < 3; ++i )
+ {
const SMDS_MeshNode* node = f->GetNode( i ), * inFaceNode=0;
- if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() ))
+
+ // get node UV on face
+ int shapeID = node->GetPosition()->GetShapeId();
+ if ( helper.IsSeamShape( shapeID ))
if ( helper.IsSeamShape( f->GetNodeWrap( i+1 )->GetPosition()->GetShapeId() ))
inFaceNode = f->GetNodeWrap( i-1 );
else
inFaceNode = f->GetNodeWrap( i+1 );
-
gp_XY uv = helper.GetNodeUV( geomFace, node, inFaceNode );
- if ( reverse ) {
- tri.GeomInfoPi(3-i).u = uv.X();
- tri.GeomInfoPi(3-i).v = uv.Y();
- tri.PNum (3-i) = ngNodeId( node, ngMesh, nodeNgIdMap );
- } else {
- tri.GeomInfoPi(i+1).u = uv.X();
- tri.GeomInfoPi(i+1).v = uv.Y();
- tri.PNum (i+1) = ngNodeId( node, ngMesh, nodeNgIdMap );
- }
+
+ int ind = reverse ? 3-i : i+1;
+ tri.GeomInfoPi(ind).u = uv.X();
+ tri.GeomInfoPi(ind).v = uv.Y();
+ tri.PNum (ind) = ngNodeId( node, ngMesh, nodeNgIdMap );
}
ngMesh.AddSurfaceElement (tri);
+#ifdef DUMP_TRIANGLES
+ cout << tri << endl;
+#endif
+ if ( isInternalFace )
+ {
+ swap( tri[1], tri[2] );
+ ngMesh.AddSurfaceElement (tri);
+#ifdef DUMP_TRIANGLES
+ cout << tri << endl;
+#endif
+ }
}
break;
- } //
+ } // case TopAbs_FACE
case TopAbs_VERTEX: { // VERTEX
// --------------------------
return true;
}
+//================================================================================
+/*!
+ * \brief Duplicate mesh faces on internal geom faces
+ */
+//================================================================================
+
+void NETGENPlugin_Mesher::fixIntFaces(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ NETGENPlugin_Internals& internalShapes)
+{
+ SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS();
+
+ // find ng indices of internal faces
+ set<int> ngFaceIds;
+ for ( int ngFaceID = 1; ngFaceID <= occgeom.fmap.Extent(); ++ngFaceID )
+ {
+ int smeshID = meshDS->ShapeToIndex( occgeom.fmap( ngFaceID ));
+ if ( internalShapes.isInternalShape( smeshID ))
+ ngFaceIds.insert( ngFaceID );
+ }
+ if ( !ngFaceIds.empty() )
+ {
+ // duplicate faces
+ int i, nbFaces = ngMesh.GetNSE();
+ for (int i = 1; i <= nbFaces; ++i)
+ {
+ netgen::Element2d elem = ngMesh.SurfaceElement(i);
+ if ( ngFaceIds.count( elem.GetIndex() ))
+ {
+ swap( elem[1], elem[2] );
+ ngMesh.AddSurfaceElement (elem);
+ }
+ }
+ }
+}
+
+namespace
+{
+ //================================================================================
+ // define gp_XY_Subtracted pointer to function calling gp_XY::Subtracted(gp_XY)
+ gp_XY_FunPtr(Subtracted);
+ //gp_XY_FunPtr(Added);
+
+ //================================================================================
+ /*!
+ * \brief Evaluate distance between two 2d points along the surface
+ */
+ //================================================================================
+
+ double evalDist( const gp_XY& uv1,
+ const gp_XY& uv2,
+ const Handle(Geom_Surface)& surf,
+ const int stopHandler=-1)
+ {
+ if ( stopHandler > 0 ) // continue recursion
+ {
+ gp_XY mid = SMESH_MesherHelper::GetMiddleUV( surf, uv1, uv2 );
+ return evalDist( uv1,mid, surf, stopHandler-1 ) + evalDist( mid,uv2, surf, stopHandler-1 );
+ }
+ double dist3D = surf->Value( uv1.X(), uv1.Y() ).Distance( surf->Value( uv2.X(), uv2.Y() ));
+ if ( stopHandler == 0 ) // stop recursion
+ return dist3D;
+
+ // start recursion if necessary
+ double dist2D = SMESH_MesherHelper::applyIn2D(surf, uv1, uv2, gp_XY_Subtracted, 0).Modulus();
+ if ( fabs( dist3D - dist2D ) < dist2D * 1e-10 )
+ return dist3D; // equal parametrization of a planar surface
+
+ return evalDist( uv1, uv2, surf, 3 ); // start recursion
+ }
+
+ //================================================================================
+ /*!
+ * \brief Data of vertex internal in geom face
+ */
+ //================================================================================
+
+ struct TIntVData
+ {
+ gp_XY uv; //!< UV in face parametric space
+ int ngId; //!< ng id of corrsponding node
+ gp_XY uvClose; //!< UV of closest boundary node
+ int ngIdClose; //!< ng id of closest boundary node
+ };
+
+ //================================================================================
+ /*!
+ * \brief Data of vertex internal in solid
+ */
+ //================================================================================
+
+ struct TIntVSoData
+ {
+ int ngId; //!< ng id of corrsponding node
+ int ngIdClose; //!< ng id of closest 2d mesh element
+ int ngIdCloseN; //!< ng id of closest node of the closest 2d mesh element
+ };
+
+ inline double dist2(const netgen::MeshPoint& p1, const netgen::MeshPoint& p2)
+ {
+ return gp_Pnt( NGPOINT_COORDS(p1)).SquareDistance( gp_Pnt( NGPOINT_COORDS(p2)));
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Make netgen take internal vertices in faces into account by adding
+ * segments including internal vertices
+ *
+ * This function works in supposition that 1D mesh is already computed in ngMesh
+ */
+//================================================================================
+
+void NETGENPlugin_Mesher::addIntVerticesInFaces(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ vector<const SMDS_MeshNode*>& nodeVec,
+ NETGENPlugin_Internals& internalShapes)
+{
+ if ( nodeVec.size() < ngMesh.GetNP() )
+ nodeVec.resize( ngMesh.GetNP(), 0 );
+
+ SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS();
+ SMESH_MesherHelper helper( internalShapes.getMesh() );
+
+ const map<int,list<int> >& face2Vert = internalShapes.getFacesWithVertices();
+ map<int,list<int> >::const_iterator f2v = face2Vert.begin();
+ for ( ; f2v != face2Vert.end(); ++f2v )
+ {
+ const TopoDS_Face& face = TopoDS::Face( meshDS->IndexToShape( f2v->first ));
+ if ( face.IsNull() ) continue;
+ int faceNgID = occgeom.fmap.FindIndex (face);
+ if ( faceNgID < 0 ) continue;
+
+ TopLoc_Location loc;
+ Handle(Geom_Surface) surf = BRep_Tool::Surface(face,loc);
+
+ helper.SetSubShape( face );
+ helper.SetElementsOnShape( true );
+
+ // Get data of internal vertices and add them to ngMesh
+
+ multimap< double, TIntVData > dist2VData; // sort vertices by distance from boundary nodes
+
+ int i, nbSegInit = ngMesh.GetNSeg();
+
+ // boundary characteristics
+ double totSegLen2D = 0;
+ int totNbSeg = 0;
+
+ const list<int>& iVertices = f2v->second;
+ list<int>::const_iterator iv = iVertices.begin();
+ for ( int nbV = 0; iv != iVertices.end(); ++iv, nbV++ )
+ {
+ TIntVData vData;
+ // get node on vertex
+ const TopoDS_Vertex V = TopoDS::Vertex( meshDS->IndexToShape( *iv ));
+ const SMDS_MeshNode * nV = SMESH_Algo::VertexNode( V, meshDS );
+ if ( !nV )
+ {
+ SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( V );
+ sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ nV = SMESH_Algo::VertexNode( V, meshDS );
+ if ( !nV ) continue;
+ }
+ // add ng node
+ netgen::MeshPoint mp( netgen::Point<3> (nV->X(), nV->Y(), nV->Z()) );
+ ngMesh.AddPoint ( mp, 1, netgen::EDGEPOINT );
+ vData.ngId = ngMesh.GetNP();
+ nodeVec.push_back( nV );
+
+ // get node UV
+ bool uvOK = false;
+ vData.uv = helper.GetNodeUV( face, nV, 0, &uvOK );
+ if ( !uvOK ) helper.CheckNodeUV( face, nV, vData.uv, BRep_Tool::Tolerance(V),/*force=*/1);
+
+ // loop on all segments of the face to find the node closest to vertex and to count
+ // average segment 2d length
+ double closeDist2 = numeric_limits<double>::max(), dist2;
+ int ngIdLast = 0;
+ for (i = 1; i <= ngMesh.GetNSeg(); ++i)
+ {
+ netgen::Segment & seg = ngMesh.LineSegment(i);
+ if ( seg.si != faceNgID ) continue;
+ gp_XY uv[2];
+ for ( int iEnd = 0; iEnd < 2; ++iEnd)
+ {
+ uv[iEnd].SetCoord( seg.epgeominfo[iEnd].u, seg.epgeominfo[iEnd].v );
+ if ( ngIdLast == seg[ iEnd ] ) continue;
+ dist2 = helper.applyIn2D(surf, uv[iEnd], vData.uv, gp_XY_Subtracted,0).SquareModulus();
+ if ( dist2 < closeDist2 )
+ vData.ngIdClose = seg[ iEnd ], vData.uvClose = uv[iEnd], closeDist2 = dist2;
+ ngIdLast = seg[ iEnd ];
+ }
+ if ( !nbV )
+ {
+ totSegLen2D += helper.applyIn2D(surf, uv[0], uv[1], gp_XY_Subtracted, false).Modulus();
+ totNbSeg++;
+ }
+ }
+ dist2VData.insert( make_pair( closeDist2, vData ));
+ }
+
+ if ( totNbSeg == 0 ) break;
+ double avgSegLen2d = totSegLen2D / totNbSeg;
+
+ // Loop on vertices to add segments
+
+ multimap< double, TIntVData >::iterator dist_vData = dist2VData.begin();
+ for ( ; dist_vData != dist2VData.end(); ++dist_vData )
+ {
+ double closeDist2 = dist_vData->first, dist2;
+ TIntVData & vData = dist_vData->second;
+
+ // try to find more close node among segments added for internal vertices
+ for (i = nbSegInit+1; i <= ngMesh.GetNSeg(); ++i)
+ {
+ netgen::Segment & seg = ngMesh.LineSegment(i);
+ if ( seg.si != faceNgID ) continue;
+ gp_XY uv[2];
+ for ( int iEnd = 0; iEnd < 2; ++iEnd)
+ {
+ uv[iEnd].SetCoord( seg.epgeominfo[iEnd].u, seg.epgeominfo[iEnd].v );
+ dist2 = helper.applyIn2D(surf, uv[iEnd], vData.uv, gp_XY_Subtracted,0).SquareModulus();
+ if ( dist2 < closeDist2 )
+ vData.ngIdClose = seg[ iEnd ], vData.uvClose = uv[iEnd], closeDist2 = dist2;
+ }
+ }
+ // decide whether to use the closest node as the second end of segment or to
+ // create a new point
+ int segEnd1 = vData.ngId;
+ int segEnd2 = vData.ngIdClose; // to use closest node
+ gp_XY uvV = vData.uv, uvP = vData.uvClose;
+ double segLenHint = ngMesh.GetH( ngMesh.Point( vData.ngId ));
+ double nodeDist2D = sqrt( closeDist2 );
+ double nodeDist3D = evalDist( vData.uv, vData.uvClose, surf );
+ bool avgLenOK = ( avgSegLen2d < 0.75 * nodeDist2D );
+ bool hintLenOK = ( segLenHint < 0.75 * nodeDist3D );
+ //cout << "uvV " << uvV.X() <<","<<uvV.Y() << " ";
+ if ( hintLenOK || avgLenOK )
+ {
+ // create a point between the closest node and V
+
+ // how far from V
+ double r = min( 0.5, ( hintLenOK ? segLenHint/nodeDist3D : avgSegLen2d/nodeDist2D ));
+ // direction from V to closet node in 2D
+ gp_Dir2d v2n( helper.applyIn2D(surf, uvP, uvV, gp_XY_Subtracted, false ));
+ // new point
+ uvP = vData.uv + r * nodeDist2D * v2n.XY();
+ gp_Pnt P = surf->Value( uvP.X(), uvP.Y() ).Transformed( loc );
+
+ netgen::MeshPoint mp( netgen::Point<3> (P.X(), P.Y(), P.Z()));
+ ngMesh.AddPoint ( mp, 1, netgen::EDGEPOINT );
+ segEnd2 = ngMesh.GetNP();
+ //cout << "Middle " << r << " uv " << uvP.X() << "," << uvP.Y() << "( " << ngMesh.Point(segEnd2).X()<<","<<ngMesh.Point(segEnd2).Y()<<","<<ngMesh.Point(segEnd2).Z()<<" )"<< endl;
+ SMDS_MeshNode * nP = helper.AddNode(P.X(), P.Y(), P.Z());
+ nodeVec.push_back( nP );
+ }
+ //else cout << "at Node " << " uv " << uvP.X() << "," << uvP.Y() << endl;
+
+ // Add the segment
+ netgen::Segment seg;
+
+ if ( segEnd1 > segEnd2 ) swap( segEnd1, segEnd2 ), swap( uvV, uvP );
+ seg[0] = segEnd1; // ng node id
+ seg[1] = segEnd2; // ng node id
+ seg.edgenr = ngMesh.GetNSeg() + 1;// segment id
+ seg.si = faceNgID;
+
+ seg.epgeominfo[ 0 ].dist = 0; // param on curve
+ seg.epgeominfo[ 0 ].u = uvV.X();
+ seg.epgeominfo[ 0 ].v = uvV.Y();
+ seg.epgeominfo[ 1 ].dist = 1; // param on curve
+ seg.epgeominfo[ 1 ].u = uvP.X();
+ seg.epgeominfo[ 1 ].v = uvP.Y();
+
+// seg.epgeominfo[ 0 ].edgenr = 10; // = geom.emap.FindIndex(edge);
+// seg.epgeominfo[ 1 ].edgenr = 10; // = geom.emap.FindIndex(edge);
+
+ ngMesh.AddSegment (seg);
+
+ // add reverse segment
+ swap (seg[0], seg[1]);
+ swap( seg.epgeominfo[0], seg.epgeominfo[1] );
+ seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
+ ngMesh.AddSegment (seg);
+ }
+
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Make netgen take internal vertices in solids into account by adding
+ * faces including internal vertices
+ *
+ * This function works in supposition that 2D mesh is already computed in ngMesh
+ */
+//================================================================================
+
+void NETGENPlugin_Mesher::addIntVerticesInSolids(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ vector<const SMDS_MeshNode*>& nodeVec,
+ NETGENPlugin_Internals& internalShapes)
+{
+#ifdef DUMP_TRIANGLES_SCRIPT
+ // create a python script making a mesh containing triangles added for internal vertices
+ ofstream py(DUMP_TRIANGLES_SCRIPT);
+ py << "from smesh import * "<< endl
+ << "m = Mesh(name='triangles')" << endl;
+#endif
+ if ( nodeVec.size() < ngMesh.GetNP() )
+ nodeVec.resize( ngMesh.GetNP(), 0 );
+
+ SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS();
+ SMESH_MesherHelper helper( internalShapes.getMesh() );
+
+ const map<int,list<int> >& so2Vert = internalShapes.getSolidsWithVertices();
+ map<int,list<int> >::const_iterator s2v = so2Vert.begin();
+ for ( ; s2v != so2Vert.end(); ++s2v )
+ {
+ const TopoDS_Shape& solid = meshDS->IndexToShape( s2v->first );
+ if ( solid.IsNull() ) continue;
+ int solidNgID = occgeom.somap.FindIndex (solid);
+ if ( solidNgID < 0 && !occgeom.somap.IsEmpty() ) continue;
+
+ helper.SetSubShape( solid );
+ helper.SetElementsOnShape( true );
+
+ // find ng indices of faces within the solid
+ set<int> ngFaceIds;
+ for (TopExp_Explorer fExp(solid, TopAbs_FACE); fExp.More(); fExp.Next() )
+ ngFaceIds.insert( occgeom.fmap.FindIndex( fExp.Current() ));
+ if ( ngFaceIds.size() == 1 && *ngFaceIds.begin() == 0 )
+ ngFaceIds.insert( 1 );
+
+ // Get data of internal vertices and add them to ngMesh
+
+ multimap< double, TIntVSoData > dist2VData; // sort vertices by distance from ng faces
+
+ int i, nbFaceInit = ngMesh.GetNSE();
+
+ // boundary characteristics
+ double totSegLen = 0;
+ int totNbSeg = 0;
+
+ const list<int>& iVertices = s2v->second;
+ list<int>::const_iterator iv = iVertices.begin();
+ for ( int nbV = 0; iv != iVertices.end(); ++iv, nbV++ )
+ {
+ TIntVSoData vData;
+ const TopoDS_Vertex V = TopoDS::Vertex( meshDS->IndexToShape( *iv ));
+
+ // get node on vertex
+ const SMDS_MeshNode * nV = SMESH_Algo::VertexNode( V, meshDS );
+ if ( !nV )
+ {
+ SMESH_subMesh* sm = helper.GetMesh()->GetSubMesh( V );
+ sm->ComputeStateEngine( SMESH_subMesh::COMPUTE );
+ nV = SMESH_Algo::VertexNode( V, meshDS );
+ if ( !nV ) continue;
+ }
+ // add ng node
+ netgen::MeshPoint mpV( netgen::Point<3> (nV->X(), nV->Y(), nV->Z()) );
+ ngMesh.AddPoint ( mpV, 1, netgen::FIXEDPOINT );
+ vData.ngId = ngMesh.GetNP();
+ nodeVec.push_back( nV );
+
+ // loop on all 2d elements to find the one closest to vertex and to count
+ // average segment length
+ double closeDist2 = numeric_limits<double>::max(), avgDist2;
+ for (i = 1; i <= ngMesh.GetNSE(); ++i)
+ {
+ const netgen::Element2d& elem = ngMesh.SurfaceElement(i);
+ if ( !ngFaceIds.count( elem.GetIndex() )) continue;
+ avgDist2 = 0;
+ multimap< double, int> dist2nID; // sort nodes of element by distance from V
+ for ( int j = 0; j < elem.GetNP(); ++j)
+ {
+ netgen::MeshPoint mp = ngMesh.Point( elem[j] );
+ double d2 = dist2( mpV, mp );
+ dist2nID.insert( make_pair( d2, elem[j] ));
+ avgDist2 += d2 / elem.GetNP();
+ if ( !nbV )
+ totNbSeg++, totSegLen+= sqrt( dist2( mp, ngMesh.Point( elem[(j+1)%elem.GetNP()])));
+ }
+ double dist = dist2nID.begin()->first; //avgDist2;
+ if ( dist < closeDist2 )
+ vData.ngIdClose= i, vData.ngIdCloseN= dist2nID.begin()->second, closeDist2= dist;
+ }
+ dist2VData.insert( make_pair( closeDist2, vData ));
+ }
+
+ if ( totNbSeg == 0 ) break;
+ double avgSegLen = totSegLen / totNbSeg;
+
+ // Loop on vertices to add triangles
+
+ multimap< double, TIntVSoData >::iterator dist_vData = dist2VData.begin();
+ for ( ; dist_vData != dist2VData.end(); ++dist_vData )
+ {
+ double closeDist2 = dist_vData->first;
+ TIntVSoData & vData = dist_vData->second;
+
+ const netgen::MeshPoint& mpV = ngMesh.Point( vData.ngId );
+
+ // try to find more close face among ones added for internal vertices
+ for (i = nbFaceInit+1; i <= ngMesh.GetNSE(); ++i)
+ {
+ double avgDist2 = 0;
+ multimap< double, int> dist2nID;
+ const netgen::Element2d& elem = ngMesh.SurfaceElement(i);
+ for ( int j = 0; j < elem.GetNP(); ++j)
+ {
+ double d = dist2( mpV, ngMesh.Point( elem[j] ));
+ dist2nID.insert( make_pair( d, elem[j] ));
+ avgDist2 += d / elem.GetNP();
+ if ( avgDist2 < closeDist2 )
+ vData.ngIdClose= i, vData.ngIdCloseN= dist2nID.begin()->second, closeDist2= avgDist2;
+ }
+ }
+ // sort nodes of the closest face by angle with vector from V to the closest node
+ const double tol = numeric_limits<double>::min();
+ map< double, int > angle2ID;
+ const netgen::Element2d& closeFace = ngMesh.SurfaceElement( vData.ngIdClose );
+ netgen::MeshPoint mp[2];
+ mp[0] = ngMesh.Point( vData.ngIdCloseN );
+ gp_XYZ p1( NGPOINT_COORDS( mp[0] ));
+ gp_XYZ pV( NGPOINT_COORDS( mpV ));
+ gp_Vec v2p1( pV, p1 );
+ double distN1 = v2p1.Magnitude();
+ if ( distN1 <= tol ) continue;
+ v2p1 /= distN1;
+ for ( int j = 0; j < closeFace.GetNP(); ++j)
+ {
+ mp[1] = ngMesh.Point( closeFace[j] );
+ gp_Vec v2p( pV, gp_Pnt( NGPOINT_COORDS( mp[1] )) );
+ angle2ID.insert( make_pair( v2p1.Angle( v2p ), closeFace[j]));
+ }
+ // get node with angle of 60 degrees or greater
+ map< double, int >::iterator angle_id = angle2ID.lower_bound( 60*PI180 );
+ if ( angle_id == angle2ID.end() ) angle_id = --angle2ID.end();
+ const double minAngle = 30 * PI180;
+ const double angle = angle_id->first;
+ bool angleOK = ( angle > minAngle );
+
+ // find points to create a triangle
+ netgen::Element2d tri(3);
+ tri.SetIndex ( 1 );
+ tri[0] = vData.ngId;
+ tri[1] = vData.ngIdCloseN; // to use the closest nodes
+ tri[2] = angle_id->second; // to use the node with best angle
+
+ // decide whether to use the closest node and the node with best angle or to create new ones
+ for ( int isBestAngleN = 0; isBestAngleN < 2; ++isBestAngleN )
+ {
+ bool createNew = !angleOK, distOK = true;
+ double distFromV;
+ int triInd = isBestAngleN ? 2 : 1;
+ mp[isBestAngleN] = ngMesh.Point( tri[triInd] );
+ if ( isBestAngleN )
+ {
+ if ( angleOK )
+ {
+ double distN2 = sqrt( dist2( mpV, mp[isBestAngleN]));
+ createNew = ( fabs( distN2 - distN1 ) > 0.25 * distN1 );
+ }
+ else if ( angle < tol )
+ {
+ v2p1.SetX( v2p1.X() + 1e-3 );
+ }
+ distFromV = distN1;
+ }
+ else
+ {
+ double segLenHint = ngMesh.GetH( ngMesh.Point( vData.ngId ));
+ bool avgLenOK = ( avgSegLen < 0.75 * distN1 );
+ bool hintLenOK = ( segLenHint < 0.75 * distN1 );
+ createNew = (createNew || avgLenOK || hintLenOK );
+ // we create a new node not closer than 0.5 to the closest face
+ // in order not to clash with other close face
+ double r = min( 0.5, ( hintLenOK ? segLenHint : avgSegLen ) / distN1 );
+ distFromV = r * distN1;
+ }
+ if ( createNew )
+ {
+ // create a new point, between the node and the vertex if angleOK
+ gp_XYZ p( NGPOINT_COORDS( mp[isBestAngleN] ));
+ gp_Vec v2p( pV, p ); v2p.Normalize();
+ if ( isBestAngleN && !angleOK )
+ p = p1 + gp_Dir( v2p.XYZ() - v2p1.XYZ()).XYZ() * distN1 * 0.95;
+ else
+ p = pV + v2p.XYZ() * distFromV;
+
+ if ( !isBestAngleN ) p1 = p, distN1 = distFromV;
+
+ mp[isBestAngleN].SetPoint( netgen::Point<3> (p.X(), p.Y(), p.Z()));
+ ngMesh.AddPoint ( mp[isBestAngleN], 1, netgen::SURFACEPOINT );
+ tri[triInd] = ngMesh.GetNP();
+ nodeVec.push_back( helper.AddNode( p.X(), p.Y(), p.Z()) );
+ }
+ }
+ ngMesh.AddSurfaceElement (tri);
+ swap( tri[1], tri[2] );
+ ngMesh.AddSurfaceElement (tri);
+
+#ifdef DUMP_TRIANGLES_SCRIPT
+ py << "n1 = m.AddNode( "<< mpV.X()<<", "<< mpV.Y()<<", "<< mpV.Z()<<") "<< endl
+ << "n2 = m.AddNode( "<< mp[0].X()<<", "<< mp[0].Y()<<", "<< mp[0].Z()<<") "<< endl
+ << "n3 = m.AddNode( "<< mp[1].X()<<", "<< mp[1].Y()<<", "<< mp[1].Z()<<" )" << endl
+ << "m.AddFace([n1,n2,n3])" << endl;
+#endif
+ } // loop on internal vertices of a solid
+
+ } // loop on solids with internal vertices
+}
+
//================================================================================
/*!
* \brief Fill SMESH mesh according to contents of netgen mesh
const netgen::Mesh& ngMesh,
const NETGENPlugin_ngMeshInfo& initState,
SMESH_Mesh& sMesh,
- std::vector<SMDS_MeshNode*>& nodeVec,
+ std::vector<const SMDS_MeshNode*>& nodeVec,
SMESH_Comment& comment)
{
int nbNod = ngMesh.GetNP();
// create and insert nodes into nodeVec
nodeVec.resize( nbNod + 1 );
int i, nbInitNod = initState._nbNodes;
- for (i = nbInitNod+1; i <= nbNod /*&& isOK*/; ++i )
+ for (i = nbInitNod+1; i <= nbNod; ++i )
{
const netgen::MeshPoint& ngPoint = ngMesh.Point(i);
SMDS_MeshNode* node = NULL;
- bool newNodeOnVertex = false;
TopoDS_Vertex aVert;
- if (i-nbInitNod <= occgeo.vmap.Extent())
+ // First, netgen creates nodes on vertices in occgeo.vmap,
+ // so node index corresponds to vertex index
+ // but (isuue 0020776) netgen does not create nodes with equal coordinates
+ if ( i-nbInitNod <= occgeo.vmap.Extent() )
{
- // point on vertex
- aVert = TopoDS::Vertex(occgeo.vmap(i-nbInitNod));
- SMESHDS_SubMesh * submesh = meshDS->MeshElements(aVert);
- if (submesh)
+ gp_Pnt p ( NGPOINT_COORDS(ngPoint) );
+ for (int iV = i-nbInitNod; aVert.IsNull() && iV <= occgeo.vmap.Extent(); ++iV)
{
- SMDS_NodeIteratorPtr it = submesh->GetNodes();
- if (it->more())
- {
- node = const_cast<SMDS_MeshNode*> (it->next());
- pindMap.Add(i);
- }
+ aVert = TopoDS::Vertex( occgeo.vmap( iV ) );
+ gp_Pnt pV = BRep_Tool::Pnt( aVert );
+ if ( p.SquareDistance( pV ) > 1e-20 )
+ aVert.Nullify();
+ else
+ node = const_cast<SMDS_MeshNode*>( SMESH_Algo::VertexNode( aVert, meshDS ));
}
- if (!node)
- newNodeOnVertex = true;
- }
- if (!node)
-#ifdef NETGEN_NEW
- node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2));
-#else
- node = meshDS->AddNode(ngPoint.X(), ngPoint.Y(), ngPoint.Z());
-#endif
- if (!node)
- {
- MESSAGE("Cannot create a mesh node");
- if ( !comment.size() ) comment << "Cannot create a mesh node";
- nbSeg = nbFac = nbVol = 0;
- break;
}
- nodeVec_ACCESS(i) = node;
- if (newNodeOnVertex)
- {
- // point on vertex
- meshDS->SetNodeOnVertex(node, aVert);
+ if (node) // node found on vertex
pindMap.Add(i);
+ else
+ {
+ node = meshDS->AddNode( NGPOINT_COORDS( ngPoint ));
+ if (!aVert.IsNull())
+ {
+ // point on vertex
+ meshDS->SetNodeOnVertex(node, aVert);
+ pindMap.Add(i);
+ }
}
+ nodeVec[i] = node;
}
// create mesh segments along geometric edges
NCollection_Map<Link> linkMap;
int nbInitSeg = initState._nbSegments;
- for (i = nbInitSeg+1; i <= nbSeg/* && isOK*/; ++i )
+ for (i = nbInitSeg+1; i <= nbSeg; ++i )
{
const netgen::Segment& seg = ngMesh.LineSegment(i);
-#ifdef NETGEN_NEW
- Link link(seg.pnums[0], seg.pnums[1]);
-#else
- Link link(seg.p1, seg.p2);
-#endif
- if (linkMap.Contains(link))
+ Link link(seg[0], seg[1]);
+ if (!linkMap.Add(link))
continue;
- linkMap.Add(link);
TopoDS_Edge aEdge;
#ifdef NETGEN_NEW
int pinds[3] = { seg.pnums[0], seg.pnums[1], seg.pnums[2] };
// create mesh faces along geometric faces
int nbInitFac = initState._nbFaces;
- for (i = nbInitFac+1; i <= nbFac/* && isOK*/; ++i )
+ for (i = nbInitFac+1; i <= nbFac; ++i )
{
const netgen::Element2d& elem = ngMesh.SurfaceElement(i);
int aGeomFaceInd = elem.GetIndex();
bool NETGENPlugin_Mesher::Compute()
{
-#ifdef WNT
- netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters();
-#else
+ NETGENPlugin_NetgenLibWrapper ngLib;
+
netgen::MeshingParameters& mparams = netgen::mparam;
-#endif
MESSAGE("Compute with:\n"
" max size = " << mparams.maxh << "\n"
" segments per edge = " << mparams.segmentsperedge);
" quad allowed = " << mparams.quad);
SMESH_ComputeErrorPtr error = SMESH_ComputeError::New();
- nglib::Ng_Init();
+
// -------------------------
// Prepare OCC geometry
netgen::OCCGeometry occgeo;
list< SMESH_subMesh* > meshedSM;
- TopTools_DataMapOfShapeShape internalEdge2Face;
- PrepareOCCgeometry( occgeo, _shape, *_mesh, &meshedSM, &internalEdge2Face );
+ NETGENPlugin_Internals internals( *_mesh, _shape, _isVolume );
+ PrepareOCCgeometry( occgeo, _shape, *_mesh, &meshedSM, &internals );
// -------------------------
// Generate the mesh
int err = 0;
// vector of nodes in which node index == netgen ID
- vector< SMDS_MeshNode* > nodeVec;
+ vector< const SMDS_MeshNode* > nodeVec;
try
{
// ----------------
// compute 1D mesh
// ----------------
- // pass 1D simple parameters to NETGEN
+ // Pass 1D simple parameters to NETGEN
if ( _simpleHyp ) {
if ( int nbSeg = _simpleHyp->GetNumberOfSegments() ) {
// nb of segments
mparams.maxh = _simpleHyp->GetLocalLength();
}
}
- // let netgen create ngMesh and calculate element size on not meshed shapes
+ // Let netgen create ngMesh and calculate element size on not meshed shapes
char *optstr = 0;
int startWith = netgen::MESHCONST_ANALYSE;
int endWith = netgen::MESHCONST_ANALYSE;
err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
if (err) comment << "Error in netgen::OCCGenerateMesh() at MESHCONST_ANALYSE step";
+ ngLib.setMesh(( Ng_Mesh*) ngMesh );
- // precompute internal edges (issue 0020676)
- if ( !err && !internalEdge2Face.IsEmpty() )
+ // Precompute internal edges (issue 0020676) in order to
+ // add mesh on them correctly (twice) to netgen mesh
+ if ( !err && internals.hasInternalEdges() )
{
- netgen::OCCGeometry intEdgeOccgeo;
- TopTools_DataMapIteratorOfDataMapOfShapeShape e2f( internalEdge2Face );
- for ( ; e2f.More(); e2f.Next() )
- {
- intEdgeOccgeo.emap.Add( e2f.Key() );
- intEdgeOccgeo.fmap.Add( e2f.Value() );
- for ( TopoDS_Iterator v(e2f.Key() ); v.More(); v.Next() )
- intEdgeOccgeo.vmap.Add( v.Value() );
- SMESH_subMesh* sm = _mesh->GetSubMesh( e2f.Key() );
- SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(/*includeSelf=*/true,true);
- while ( smIt->more() ) meshedSM.push_back( smIt->next() );
- }
- intEdgeOccgeo.boundingbox = occgeo.boundingbox;
- intEdgeOccgeo.shape = occgeo.shape;
+ // load internal shapes into OCCGeometry
+ netgen::OCCGeometry intOccgeo;
+ internals.getInternalEdges( intOccgeo.fmap, intOccgeo.emap, intOccgeo.vmap, meshedSM);
+ intOccgeo.boundingbox = occgeo.boundingbox;
+ intOccgeo.shape = occgeo.shape;
+ // let netgen compute element size by the main geometry in temporary mesh
netgen::Mesh *tmpNgMesh = NULL;
netgen::OCCGenerateMesh(occgeo, tmpNgMesh, startWith, endWith, optstr);
+ // compute mesh on internal edges
endWith = netgen::MESHCONST_MESHEDGES;
- err = netgen::OCCGenerateMesh(intEdgeOccgeo, tmpNgMesh, startWith, endWith, optstr);
+ err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, startWith, endWith, optstr);
if (err) comment << "Error in netgen::OCCGenerateMesh() at meshing internal edges";
- vector< SMDS_MeshNode* > tmpNodeVec;
- FillSMesh( intEdgeOccgeo, *tmpNgMesh, initState, *_mesh, tmpNodeVec, comment );
+ // fill SMESH by netgen mesh
+ vector< const SMDS_MeshNode* > tmpNodeVec;
+ FillSMesh( intOccgeo, *tmpNgMesh, initState, *_mesh, tmpNodeVec, comment );
err = ( !comment.empty() );
nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)tmpNgMesh);
}
- // fill ngMesh with nodes and elements of computed submeshes
+ // Fill ngMesh with nodes and elements of computed submeshes
if ( !err )
{
+ _faceDescriptors.clear();
err = ! fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM);
}
initState = NETGENPlugin_ngMeshInfo(ngMesh);
- // compute mesh
+ // Compute 1d mesh
if (!err)
{
startWith = endWith = netgen::MESHCONST_MESHEDGES;
// ---------------------
if (!err)
{
- // pass 2D simple parameters to NETGEN
+ // Pass 2D simple parameters to NETGEN
if ( _simpleHyp ) {
if ( double area = _simpleHyp->GetMaxElementArea() ) {
// face area
}
else {
// length from edges
- double length = 0;
- TopTools_MapOfShape tmpMap;
- for ( TopExp_Explorer exp( _shape, TopAbs_EDGE ); exp.More(); exp.Next() )
- if( tmpMap.Add(exp.Current()) )
- length += SMESH_Algo::EdgeLength( TopoDS::Edge( exp.Current() ));
-
if ( ngMesh->GetNSeg() ) {
+ double edgeLength = 0;
+ TopTools_MapOfShape visitedEdges;
+ for ( TopExp_Explorer exp( _shape, TopAbs_EDGE ); exp.More(); exp.Next() )
+ if( visitedEdges.Add(exp.Current()) )
+ edgeLength += SMESH_Algo::EdgeLength( TopoDS::Edge( exp.Current() ));
// we have to multiply length by 2 since for each TopoDS_Edge there
// are double set of NETGEN edges or, in other words, we have to
- // divide ngMesh->GetNSeg() on 2.
- mparams.maxh = 2*length / ngMesh->GetNSeg();
+ // divide ngMesh->GetNSeg() by 2.
+ mparams.maxh = 2*edgeLength / ngMesh->GetNSeg();
}
- else
+ else {
mparams.maxh = 1000;
+ }
mparams.grading = 0.2; // slow size growth
}
mparams.maxh = min( mparams.maxh, occgeo.boundingbox.Diam()/2 );
bb.Increase (bb.Diam()/20);
ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparams.grading);
}
- // let netgen compute 2D mesh
+
+ // Care of vertices internal in faces (issue 0020676)
+ if ( internals.hasInternalVertexInFace() )
+ {
+ // store computed segments in SMESH in order not to create SMESH
+ // edges for ng segments added by addIntVerticesInFaces()
+ FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment );
+ // add segments to faces with internal vertices
+ addIntVerticesInFaces( occgeo, *ngMesh, nodeVec, internals );
+ initState = NETGENPlugin_ngMeshInfo(ngMesh);
+ }
+
+ // Precompute internal faces (issue 0020676) in order to
+ // add mesh on them correctly (twice to emulate the crack) to netgen mesh
+ //if ( internals.hasInternalFaces() )
+ // {
+// // fill SMESH with generated segments
+// FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment );
+
+// // load internal shapes into a separate OCCGeometry
+// netgen::OCCGeometry intOccgeo;
+// list< SMESH_subMesh* > boundarySM;
+// internals.getInternalFaces( intOccgeo.fmap, intOccgeo.emap, meshedSM, boundarySM);
+// intOccgeo.boundingbox = occgeo.boundingbox;
+// intOccgeo.shape = occgeo.shape;
+// intOccgeo.facemeshstatus.SetSize (intOccgeo.fmap.Extent());
+// intOccgeo.facemeshstatus = 0;
+
+// // let netgen compute element size by the main geometry in temporary mesh
+// int start = netgen::MESHCONST_ANALYSE, end = netgen::MESHCONST_ANALYSE;
+// netgen::Mesh *tmpNgMesh = NULL;
+// netgen::OCCGenerateMesh(occgeo, tmpNgMesh, start, end, optstr);
+
+// // add already computed elements from submeshes of internal faces to tmpNgMesh
+// vector< const SMDS_MeshNode* > tmpNodeVec;
+// fillNgMesh(intOccgeo, *tmpNgMesh, tmpNodeVec, boundarySM);
+// addIntVerticesInFaces( intOccgeo, *tmpNgMesh, tmpNodeVec, internals );
+
+// // compute mesh on internal faces
+// NETGENPlugin_ngMeshInfo prevState(tmpNgMesh);
+// start = netgen::MESHCONST_MESHEDGES;
+// end = netgen::MESHCONST_MESHSURFACE;
+// err = netgen::OCCGenerateMesh(intOccgeo, tmpNgMesh, start, end, optstr);
+// if (err) comment << "Error in netgen::OCCGenerateMesh() at meshing internal faces";
+
+// // fill SMESH with computed elements
+// FillSMesh( intOccgeo, *tmpNgMesh, prevState, *_mesh, tmpNodeVec, comment );
+// err = ( !comment.empty() );
+
+// // finally, correctly add elements on internal faces to netgen mesh
+// err = ! fillNgMesh(occgeo, *ngMesh, nodeVec, meshedSM);
+// initState = NETGENPlugin_ngMeshInfo(ngMesh);
+
+// nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)tmpNgMesh);
+// }
+
+ // Let netgen compute 2D mesh
startWith = netgen::MESHCONST_MESHSURFACE;
endWith = _optimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE;
err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
// ---------------------
if (!err && _isVolume)
{
- // add ng face descriptors of meshed faces
+ // Add ng face descriptors of meshed faces
map< int, pair<int,int> >::iterator fId_soIds = _faceDescriptors.begin();
for ( ; fId_soIds != _faceDescriptors.end(); ++fId_soIds ) {
int faceID = fId_soIds->first;
int solidID2 = fId_soIds->second.second;
ngMesh->AddFaceDescriptor (netgen::FaceDescriptor(faceID, solidID1, solidID2, 0));
}
- // pass 3D simple parameters to NETGEN
+ // Pass 3D simple parameters to NETGEN
const NETGENPlugin_SimpleHypothesis_3D* simple3d =
dynamic_cast< const NETGENPlugin_SimpleHypothesis_3D* > ( _simpleHyp );
if ( simple3d ) {
mparams.grading = 0.4;
ngMesh->CalcLocalH();
}
- // let netgen compute 3D mesh
+ // Care of vertices internal in solids and internal faces (issue 0020676)
+ if ( internals.hasInternalVertexInSolid() || internals.hasInternalFaces() )
+ {
+ // store computed faces in SMESH in order not to create SMESH
+ // faces for ng faces added here
+ FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment );
+ // add ng faces to solids with internal vertices
+ addIntVerticesInSolids( occgeo, *ngMesh, nodeVec, internals );
+ // duplicate mesh faces on internal faces
+ fixIntFaces( occgeo, *ngMesh, internals );
+ initState = NETGENPlugin_ngMeshInfo(ngMesh);
+ }
+ // Let netgen compute 3D mesh
startWith = netgen::MESHCONST_MESHVOLUME;
endWith = _optimize ? netgen::MESHCONST_OPTVOLUME : netgen::MESHCONST_MESHVOLUME;
err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
// ------------------------------------------------------------
if ( true /*isOK*/ ) // get whatever built
- FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment );
+ FillSMesh( occgeo, *ngMesh, initState, *_mesh, nodeVec, comment ); //!<
+ SMESH_ComputeErrorPtr readErr = readErrors(nodeVec);
+ if ( readErr && !readErr->myBadElements.empty() )
+ error = readErr;
if ( error->IsOK() && ( !isOK || comment.size() > 0 ))
error->myName = COMPERR_ALGO_FAILED;
// set bad compute error to subshapes of all failed subshapes shapes
if ( !error->IsOK() && err )
{
+ bool pb2D = false;
for (int i = 1; i <= occgeo.fmap.Extent(); i++) {
int status = occgeo.facemeshstatus[i-1];
if (status == 1 ) continue;
+ pb2D = true;
if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.fmap( i ))) {
SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
if ( !smError || smError->IsOK() ) {
if ( status == -1 )
- smError.reset( new SMESH_ComputeError( error->myName, error->myComment ));
+ smError.reset( new SMESH_ComputeError( *error ));
else
smError.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, "Ignored" ));
}
}
}
+ if ( !pb2D ) // all faces are OK
+ for (int i = 1; i <= occgeo.somap.Extent(); i++)
+ if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( occgeo.somap( i )))
+ {
+ bool smComputed = !sm->IsEmpty();
+ if ( smComputed && internals.hasInternalVertexInSolid( sm->GetId() ))
+ {
+ int nbIntV = internals.getSolidsWithVertices().find( sm->GetId() )->second.size();
+ SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
+ smComputed = ( smDS->NbElements() > 0 || smDS->NbNodes() > nbIntV );
+ }
+ SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
+ if ( !smComputed && ( !smError || smError->IsOK() ))
+ smError.reset( new SMESH_ComputeError( *error ));
+ }
}
- nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh);
- nglib::Ng_Exit();
-
- RemoveTmpFiles();
-
return error->IsOK();
}
//=============================================================================
bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap)
{
-#ifdef WNT
- netgen::MeshingParameters& mparams = netgen::GlobalMeshingParameters();
-#else
netgen::MeshingParameters& mparams = netgen::mparam;
-#endif
// -------------------------
}
}
// let netgen create ngMesh and calculate element size on not meshed shapes
- nglib::Ng_Init();
+ NETGENPlugin_NetgenLibWrapper ngLib;
netgen::Mesh *ngMesh = NULL;
char *optstr = 0;
int startWith = netgen::MESHCONST_ANALYSE;
int endWith = netgen::MESHCONST_MESHEDGES;
int err = netgen::OCCGenerateMesh(occgeo, ngMesh, startWith, endWith, optstr);
+ ngLib.setMesh(( Ng_Mesh*) ngMesh );
if (err) {
if ( SMESH_subMesh* sm = _mesh->GetSubMeshContaining( _shape ))
sm->GetComputeError().reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED ));
for (int i = 1; i <= ngMesh->GetNSeg(); ++i )
{
const netgen::Segment& seg = ngMesh->LineSegment(i);
-#ifdef NETGEN_NEW
- Link link(seg.pnums[0], seg.pnums[1]);
-#else
- Link link(seg.p1, seg.p2);
-#endif
+ Link link(seg[0], seg[1]);
if ( !linkMap.Add( link )) continue;
int aGeomEdgeInd = seg.epgeominfo[0].edgenr;
if (aGeomEdgeInd > 0 && aGeomEdgeInd <= occgeo.emap.Extent())
fullNbSeg += aVec[ entity ];
Edge2NbSeg( Edge2NbSegIt.Key() ) = aVec[ entity ];
}
- nglib::Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh);
- nglib::Ng_Exit();
// ----------------
// evaluate 2D
//================================================================================
/*!
- * \brief remove given file
+ * \brief Remove "test.out" and "problemfaces" files in current directory
*/
//================================================================================
-static void removeFile( const TCollection_AsciiString& fileName )
+void NETGENPlugin_Mesher::RemoveTmpFiles()
{
- try {
- OSD_File( fileName ).Remove();
- }
- catch ( Standard_ProgramError ) {
- MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied");
- }
+ SMESH_File("test.out").remove();
+ SMESH_File("problemfaces").remove();
+ SMESH_File("occmesh.rep").remove();
}
//================================================================================
/*!
- * \brief Remove "test.out" and "problemfaces" files in current directory
+ * \brief Read mesh entities preventing successful computation from "test.out" file
*/
//================================================================================
-void NETGENPlugin_Mesher::RemoveTmpFiles()
+SMESH_ComputeErrorPtr
+NETGENPlugin_Mesher::readErrors(const vector<const SMDS_MeshNode* >& nodeVec)
{
- removeFile("test.out");
- removeFile("problemfaces");
- removeFile("occmesh.rep");
+ SMESH_ComputeErrorPtr err = SMESH_ComputeError::New
+ (COMPERR_BAD_INPUT_MESH, "Some edges multiple times in surface mesh");
+ SMESH_File file("test.out");
+ vector<int> two(2);
+ const char* badEdgeStr = " multiple times in surface mesh";
+ const int badEdgeStrLen = strlen( badEdgeStr );
+ while( !file.eof() )
+ {
+ if ( strncmp( file, "Edge ", 5 ) == 0 &&
+ file.getInts( two ) &&
+ strncmp( file, badEdgeStr, badEdgeStrLen ) == 0 &&
+ two[0] < nodeVec.size() && two[1] < nodeVec.size())
+ {
+ err->myBadElements.push_back( new SMDS_MeshEdge( nodeVec[ two[0]], nodeVec[ two[1]] ));
+ file += badEdgeStrLen;
+ }
+ else if ( strncmp( file, "Intersecting: ", 14 ) == 0 )
+ {
+// Intersecting:
+// openelement 18 with open element 126
+// 41 36 38
+// 69 70 72
+ vector<int> three1(3), three2(3);
+ file.getLine();
+ const char* pos = file;
+ bool ok = ( strncmp( file, "openelement ", 12 ) == 0 );
+ ok = ok && file.getInts( two );
+ ok = ok && file.getInts( three1 );
+ ok = ok && file.getInts( three2 );
+ for ( int i = 0; ok && i < 3; ++i )
+ ok = ( three1[i] < nodeVec.size() && nodeVec[ three1[i]]);
+ for ( int i = 0; ok && i < 3; ++i )
+ ok = ( three2[i] < nodeVec.size() && nodeVec[ three2[i]]);
+ if ( ok )
+ {
+ err->myBadElements.push_back( new SMDS_FaceOfNodes( nodeVec[ three1[0]],
+ nodeVec[ three1[1]],
+ nodeVec[ three1[2]]));
+ err->myBadElements.push_back( new SMDS_FaceOfNodes( nodeVec[ three2[0]],
+ nodeVec[ three2[1]],
+ nodeVec[ three2[2]]));
+ err->myComment = "Intersecting triangles";
+ }
+ else
+ {
+ file.setPos( pos );
+ }
+ }
+ else
+ {
+ ++file;
+ }
+ }
+ return err;
}
//================================================================================
_nbNodes = _nbSegments = _nbFaces = _nbVolumes = 0;
}
}
+
+//================================================================================
+/*!
+ * \brief Find "internal" sub-shapes
+ */
+//================================================================================
+
+NETGENPlugin_Internals::NETGENPlugin_Internals( SMESH_Mesh& mesh,
+ const TopoDS_Shape& shape,
+ bool is3D )
+ : _mesh( mesh ), _is3D( is3D )
+{
+ SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+ TopExp_Explorer f,e;
+ for ( f.Init( shape, TopAbs_FACE ); f.More(); f.Next() )
+ {
+ int faceID = meshDS->ShapeToIndex( f.Current() );
+
+ // find not computed internal edges
+
+ for ( e.Init( f.Current().Oriented(TopAbs_FORWARD), TopAbs_EDGE ); e.More(); e.Next() )
+ if ( e.Current().Orientation() == TopAbs_INTERNAL )
+ {
+ SMESH_subMesh* eSM = mesh.GetSubMesh( e.Current() );
+ if ( eSM->IsEmpty() )
+ {
+ _e2face.insert( make_pair( eSM->GetId(), faceID ));
+ for ( TopoDS_Iterator v(e.Current()); v.More(); v.Next() )
+ _e2face.insert( make_pair( meshDS->ShapeToIndex( v.Value() ), faceID ));
+ }
+ }
+
+ // find internal vertices in a face
+ set<int> intVV; // issue 0020850 where same vertex is twice in a face
+ for ( TopoDS_Iterator fSub( f.Current() ); fSub.More(); fSub.Next())
+ if ( fSub.Value().ShapeType() == TopAbs_VERTEX )
+ {
+ int vID = meshDS->ShapeToIndex( fSub.Value() );
+ if ( intVV.insert( vID ).second )
+ _f2v[ faceID ].push_back( vID );
+ }
+
+ if ( is3D )
+ {
+ // find internal faces and their subshapes where nodes are to be doubled
+ // to make a crack with non-sewed borders
+
+ if ( f.Current().Orientation() == TopAbs_INTERNAL )
+ {
+ _intShapes.insert( meshDS->ShapeToIndex( f.Current() ));
+
+ // egdes
+ list< TopoDS_Shape > edges;
+ for ( e.Init( f.Current(), TopAbs_EDGE ); e.More(); e.Next())
+ if ( SMESH_MesherHelper::NbAncestors( e.Current(), mesh, TopAbs_FACE ) > 1 )
+ {
+ _intShapes.insert( meshDS->ShapeToIndex( e.Current() ));
+ edges.push_back( e.Current() );
+ // find border faces
+ PShapeIteratorPtr fIt =
+ SMESH_MesherHelper::GetAncestors( edges.back(),mesh,TopAbs_FACE );
+ while ( const TopoDS_Shape* pFace = fIt->next() )
+ if ( !pFace->IsSame( f.Current() ))
+ _borderFaces.insert( meshDS->ShapeToIndex( *pFace ));
+ }
+ // vertices
+ // we consider vertex internal if it is shared by more than one internal edge
+ list< TopoDS_Shape >::iterator edge = edges.begin();
+ for ( ; edge != edges.end(); ++edge )
+ for ( TopoDS_Iterator v( *edge ); v.More(); v.Next() )
+ {
+ set<int> internalEdges;
+ PShapeIteratorPtr eIt =
+ SMESH_MesherHelper::GetAncestors( v.Value(),mesh,TopAbs_EDGE );
+ while ( const TopoDS_Shape* pEdge = eIt->next() )
+ {
+ int edgeID = meshDS->ShapeToIndex( *pEdge );
+ if ( isInternalShape( edgeID ))
+ internalEdges.insert( edgeID );
+ }
+ if ( internalEdges.size() > 1 )
+ _intShapes.insert( meshDS->ShapeToIndex( v.Value() ));
+ }
+ }
+ }
+ } // loop on geom faces
+
+ // find vertices internal in solids
+ if ( is3D )
+ {
+ for ( TopExp_Explorer so(shape, TopAbs_SOLID); so.More(); so.Next())
+ {
+ int soID = meshDS->ShapeToIndex( so.Current() );
+ for ( TopoDS_Iterator soSub( so.Current() ); soSub.More(); soSub.Next())
+ if ( soSub.Value().ShapeType() == TopAbs_VERTEX )
+ _s2v[ soID ].push_back( meshDS->ShapeToIndex( soSub.Value() ));
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Find mesh faces on non-internal geom faces sharing internal edge
+ * some nodes of which are to be doubled to make the second border of the "crack"
+ */
+//================================================================================
+
+void NETGENPlugin_Internals::findBorderElements( TIDSortedElemSet & borderElems )
+{
+ if ( _intShapes.empty() ) return;
+
+ SMESH_Mesh& mesh = const_cast<SMESH_Mesh&>(_mesh);
+ SMESHDS_Mesh* meshDS = mesh.GetMeshDS();
+
+ // loop on internal geom edges
+ set<int>::const_iterator intShapeId = _intShapes.begin();
+ for ( ; intShapeId != _intShapes.end(); ++intShapeId )
+ {
+ const TopoDS_Shape& s = meshDS->IndexToShape( *intShapeId );
+ if ( s.ShapeType() != TopAbs_EDGE ) continue;
+
+ // get internal and non-internal geom faces sharing the internal edge <s>
+ int intFace = 0;
+ set<int>::iterator bordFace = _borderFaces.end();
+ PShapeIteratorPtr faces = SMESH_MesherHelper::GetAncestors( s, _mesh, TopAbs_FACE );
+ while ( const TopoDS_Shape* pFace = faces->next() )
+ {
+ int faceID = meshDS->ShapeToIndex( *pFace );
+ if ( isInternalShape( faceID ))
+ intFace = faceID;
+ else
+ bordFace = _borderFaces.insert( faceID ).first;
+ }
+ if ( bordFace == _borderFaces.end() || !intFace ) continue;
+
+ // get all links of mesh faces on internal geom face sharing nodes on edge <s>
+ set< SMESH_OrientedLink > links; //!< links of faces on internal geom face
+ list<const SMDS_MeshElement*> suspectFaces[2]; //!< mesh faces on border geom faces
+ int nbSuspectFaces = 0;
+ SMESHDS_SubMesh* intFaceSM = meshDS->MeshElements( intFace );
+ if ( !intFaceSM || intFaceSM->NbElements() == 0 ) continue;
+ SMESH_subMeshIteratorPtr smIt = mesh.GetSubMesh( s )->getDependsOnIterator(true,true);
+ while ( smIt->more() )
+ {
+ SMESHDS_SubMesh* sm = smIt->next()->GetSubMeshDS();
+ if ( !sm ) continue;
+ SMDS_NodeIteratorPtr nIt = sm->GetNodes();
+ while ( nIt->more() )
+ {
+ const SMDS_MeshNode* nOnEdge = nIt->next();
+ SMDS_ElemIteratorPtr fIt = nOnEdge->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+ int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 );
+ if ( intFaceSM->Contains( f ))
+ {
+ for ( int i = 0; i < nbNodes; ++i )
+ links.insert( SMESH_OrientedLink( f->GetNode(i), f->GetNode((i+1)%nbNodes)));
+ }
+ else
+ {
+ int nbDblNodes = 0;
+ for ( int i = 0; i < nbNodes; ++i )
+ nbDblNodes += isInternalShape( f->GetNode(i)->GetPosition()->GetShapeId() );
+ if ( nbDblNodes )
+ suspectFaces[ nbDblNodes < 2 ].push_back( f );
+ nbSuspectFaces++;
+ }
+ }
+ }
+ }
+ // suspectFaces[0] having link with same orientation as mesh faces on
+ // the internal geom face are <borderElems>. suspectFaces[1] have
+ // only one node on edge <s>, we decide on them later (at the 2nd loop)
+ // by links of <borderElems> found at the 1st and 2nd loops
+ set< SMESH_OrientedLink > borderLinks;
+ for ( int isPostponed = 0; isPostponed < 2; ++isPostponed )
+ {
+ list<const SMDS_MeshElement*>::iterator fIt = suspectFaces[isPostponed].begin();
+ for ( int nbF = 0; fIt != suspectFaces[isPostponed].end(); ++fIt, ++nbF )
+ {
+ const SMDS_MeshElement* f = *fIt;
+ bool isBorder = false, linkFound = false, borderLinkFound = false;
+ list< SMESH_OrientedLink > faceLinks;
+ int nbNodes = f->NbNodes() / ( f->IsQuadratic() ? 2 : 1 );
+ for ( int i = 0; i < nbNodes; ++i )
+ {
+ SMESH_OrientedLink link( f->GetNode(i), f->GetNode((i+1)%nbNodes));
+ faceLinks.push_back( link );
+ if ( !linkFound )
+ {
+ set< SMESH_OrientedLink >::iterator foundLink = links.find( link );
+ if ( foundLink != links.end() )
+ {
+ linkFound= true;
+ isBorder = ( foundLink->_reversed == link._reversed );
+ if ( !isBorder && !isPostponed ) break;
+ faceLinks.pop_back();
+ }
+ else if ( isPostponed && !borderLinkFound )
+ {
+ foundLink = borderLinks.find( link );
+ if ( foundLink != borderLinks.end() )
+ {
+ borderLinkFound = true;
+ isBorder = ( foundLink->_reversed != link._reversed );
+ }
+ }
+ }
+ }
+ if ( isBorder )
+ {
+ borderElems.insert( f );
+ borderLinks.insert( faceLinks.begin(), faceLinks.end() );
+ }
+ else if ( !linkFound && !borderLinkFound )
+ {
+ suspectFaces[1].push_back( f );
+ if ( nbF > 2 * nbSuspectFaces )
+ break; // dead loop protection
+ }
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief put internal shapes in maps and fill in submeshes to precompute
+ */
+//================================================================================
+
+void NETGENPlugin_Internals::getInternalEdges( TopTools_IndexedMapOfShape& fmap,
+ TopTools_IndexedMapOfShape& emap,
+ TopTools_IndexedMapOfShape& vmap,
+ list< SMESH_subMesh* >& smToPrecompute)
+{
+ if ( !hasInternalEdges() ) return;
+ map<int,int>::const_iterator ev_face = _e2face.begin();
+ for ( ; ev_face != _e2face.end(); ++ev_face )
+ {
+ const TopoDS_Shape& ev = _mesh.GetMeshDS()->IndexToShape( ev_face->first );
+ const TopoDS_Shape& face = _mesh.GetMeshDS()->IndexToShape( ev_face->second );
+
+ ( ev.ShapeType() == TopAbs_EDGE ? emap : vmap ).Add( ev );
+ fmap.Add( face );
+ //cout<<"INTERNAL EDGE or VERTEX "<<ev_face->first<<" on face "<<ev_face->second<<endl;
+
+ smToPrecompute.push_back( _mesh.GetSubMeshContaining( ev_face->first ));
+ }
+}
+
+//================================================================================
+/*!
+ * \brief return shapes and submeshes to be meshed and already meshed boundary submeshes
+ */
+//================================================================================
+
+void NETGENPlugin_Internals::getInternalFaces( TopTools_IndexedMapOfShape& fmap,
+ TopTools_IndexedMapOfShape& emap,
+ list< SMESH_subMesh* >& intFaceSM,
+ list< SMESH_subMesh* >& boundarySM)
+{
+ if ( !hasInternalFaces() ) return;
+
+ // <fmap> and <emap> are for not yet meshed shapes
+ // <intFaceSM> is for submeshes of faces
+ // <boundarySM> is for meshed edges and vertices
+
+ intFaceSM.clear();
+ boundarySM.clear();
+
+ set<int> shapeIDs ( _intShapes );
+ if ( !_borderFaces.empty() )
+ shapeIDs.insert( _borderFaces.begin(), _borderFaces.end() );
+
+ set<int>::const_iterator intS = shapeIDs.begin();
+ for ( ; intS != shapeIDs.end(); ++intS )
+ {
+ SMESH_subMesh* sm = _mesh.GetSubMeshContaining( *intS );
+
+ if ( sm->GetSubShape().ShapeType() != TopAbs_FACE ) continue;
+
+ intFaceSM.push_back( sm );
+
+ // add submeshes of not computed internal faces
+ if ( !sm->IsEmpty() ) continue;
+
+ SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(true,true);
+ while ( smIt->more() )
+ {
+ sm = smIt->next();
+ const TopoDS_Shape& s = sm->GetSubShape();
+
+ if ( sm->IsEmpty() )
+ {
+ // not yet meshed
+ switch ( s.ShapeType() ) {
+ case TopAbs_FACE: fmap.Add ( s ); break;
+ case TopAbs_EDGE: emap.Add ( s ); break;
+ default:;
+ }
+ }
+ else
+ {
+ if ( s.ShapeType() != TopAbs_FACE )
+ boundarySM.push_back( sm );
+ }
+ }
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Return true if given shape is to be precomputed in order to be correctly
+ * added to netgen mesh
+ */
+//================================================================================
+
+bool NETGENPlugin_Internals::isShapeToPrecompute(const TopoDS_Shape& s)
+{
+ int shapeID = _mesh.GetMeshDS()->ShapeToIndex( s );
+ switch ( s.ShapeType() ) {
+ case TopAbs_FACE : break; //return isInternalShape( shapeID ) || isBorderFace( shapeID );
+ case TopAbs_EDGE : return isInternalEdge( shapeID );
+ case TopAbs_VERTEX: break;
+ default:;
+ }
+ return false;
+}
+
+//================================================================================
+/*!
+ * \brief Return SMESH
+ */
+//================================================================================
+
+SMESH_Mesh& NETGENPlugin_Internals::getMesh() const
+{
+ return const_cast<SMESH_Mesh&>( _mesh );
+}
+
+//================================================================================
+/*!
+ * \brief Initialize netgen library
+ */
+//================================================================================
+
+NETGENPlugin_NetgenLibWrapper::NETGENPlugin_NetgenLibWrapper()
+{
+ Ng_Init();
+ _ngMesh = Ng_NewMesh();
+}
+
+//================================================================================
+/*!
+ * \brief Finish using netgen library
+ */
+//================================================================================
+
+NETGENPlugin_NetgenLibWrapper::~NETGENPlugin_NetgenLibWrapper()
+{
+ Ng_DeleteMesh( _ngMesh );
+ Ng_Exit();
+ NETGENPlugin_Mesher::RemoveTmpFiles();
+}
+
+//================================================================================
+/*!
+ * \brief Set netgen mesh to delete at destruction
+ */
+//================================================================================
+
+void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh )
+{
+ if ( _ngMesh )
+ Ng_DeleteMesh( _ngMesh );
+ _ngMesh = mesh;
+}
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_Mesher.hxx
// Author : Michael Sazonov (OCN)
#include "NETGENPlugin_Defs.hxx"
#include "StdMeshers_FaceSide.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMESH_Algo.hxx"
+
+namespace nglib {
+#include <nglib.h>
+}
+
#include <map>
+#include <vector>
+#include <set>
class SMESH_Mesh;
class SMESH_Comment;
class SMESHDS_Mesh;
class TopoDS_Shape;
class TopTools_DataMapOfShapeShape;
+class TopTools_IndexedMapOfShape;
class NETGENPlugin_Hypothesis;
class NETGENPlugin_SimpleHypothesis_2D;
+class NETGENPlugin_Internals;
namespace netgen {
class OCCGeometry;
class Mesh;
NETGENPlugin_Mesher (SMESH_Mesh* mesh, const TopoDS_Shape& aShape,
const bool isVolume);
- void SetParameters(const NETGENPlugin_Hypothesis* hyp);
+ void SetParameters(const NETGENPlugin_Hypothesis* hyp);
void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp);
bool Compute();
const TopoDS_Shape& shape,
SMESH_Mesh& mesh,
std::list< SMESH_subMesh* > * meshedSM=0,
- TopTools_DataMapOfShapeShape* internalE2F=0);
+ NETGENPlugin_Internals* internalShapes=0);
static int FillSMesh(const netgen::OCCGeometry& occgeom,
const netgen::Mesh& ngMesh,
const NETGENPlugin_ngMeshInfo& initState,
SMESH_Mesh& sMesh,
- std::vector<SMDS_MeshNode*>& nodeVec,
+ std::vector<const SMDS_MeshNode*>& nodeVec,
SMESH_Comment& comment);
- bool fillNgMesh(netgen::OCCGeometry& occgeom,
+ bool fillNgMesh(const netgen::OCCGeometry& occgeom,
netgen::Mesh& ngMesh,
- std::vector<SMDS_MeshNode*>& nodeVec,
+ std::vector<const SMDS_MeshNode*>& nodeVec,
const std::list< SMESH_subMesh* > & meshedSM);
+ static void fixIntFaces(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ NETGENPlugin_Internals& internalShapes);
+
+ static void addIntVerticesInFaces(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ std::vector<const SMDS_MeshNode*>& nodeVec,
+ NETGENPlugin_Internals& internalShapes);
+
+ static void addIntVerticesInSolids(const netgen::OCCGeometry& occgeom,
+ netgen::Mesh& ngMesh,
+ std::vector<const SMDS_MeshNode*>& nodeVec,
+ NETGENPlugin_Internals& internalShapes);
+
void defaultParameters();
static void RemoveTmpFiles();
+ static SMESH_ComputeErrorPtr readErrors(const std::vector< const SMDS_MeshNode* >& nodeVec);
+
private:
SMESH_Mesh* _mesh;
const TopoDS_Shape& _shape;
std::map< int, std::pair<int,int> > _faceDescriptors;
};
+//=============================================================================
+/*!
+ * \brief Container of info needed to solve problems with internal shapes.
+ *
+ * Issue 0020676. It is made up as a class to be ready to extract from NETGEN
+ * and put in SMESH as soon as the same solution is needed somewhere else.
+ * The approach is to precompute internal edges in 2D and internal faces in 3D
+ * and put their mesh correctly (twice) into netgen mesh.
+ * In 2D, this class finds internal edges in faces and their vertices.
+ * In 3D, it additionally finds internal faces, their edges shared with other faces,
+ * and their vertices shared by several internal edges. Nodes built on the found
+ * shapes and mesh faces built on the found internal faces are to be doubled in
+ * netgen mesh to emulate a "crack"
+ *
+ * For internal faces a more simple solution is found, which is just to duplicate
+ * mesh faces on internal geom faces without modeling a "real crack". For this
+ * reason findBorderElements() is no more used anywhere.
+ */
+//=============================================================================
+
+class NETGENPLUGIN_EXPORT NETGENPlugin_Internals
+{
+ SMESH_Mesh& _mesh;
+ bool _is3D;
+ //2D
+ std::map<int,int> _e2face;//!<edges and their vertices in faces where they are TopAbs_INTERNAL
+ std::map<int,std::list<int> > _f2v;//!<faces with internal vertices
+ // 3D
+ std::set<int> _intShapes;
+ std::set<int> _borderFaces; //!< non-intrnal faces sharing the internal edge
+ std::map<int,std::list<int> > _s2v;//!<solids with internal vertices
+
+public:
+ NETGENPlugin_Internals( SMESH_Mesh& mesh, const TopoDS_Shape& shape, bool is3D );
+
+ SMESH_Mesh& getMesh() const;
+
+ bool isShapeToPrecompute(const TopoDS_Shape& s);
+
+ // 2D meshing
+ // edges
+ bool hasInternalEdges() const { return !_e2face.empty(); }
+ bool isInternalEdge( int id ) const { return _e2face.count( id ); }
+ const std::map<int,int>& getEdgesAndVerticesWithFaces() const { return _e2face; }
+ void getInternalEdges( TopTools_IndexedMapOfShape& fmap,
+ TopTools_IndexedMapOfShape& emap,
+ TopTools_IndexedMapOfShape& vmap,
+ std::list< SMESH_subMesh* >& smToPrecompute);
+ // vertices
+ bool hasInternalVertexInFace() const { return !_f2v.empty(); }
+ const std::map<int,std::list<int> >& getFacesWithVertices() const { return _f2v; }
+
+ // 3D meshing
+ // faces
+ bool hasInternalFaces() const { return !_intShapes.empty(); }
+ bool isInternalShape( int id ) const { return _intShapes.count( id ); }
+ void findBorderElements( std::set< const SMDS_MeshElement*, TIDCompare > & borderElems );
+ bool isBorderFace( int faceID ) const { return _borderFaces.count( faceID ); }
+ void getInternalFaces( TopTools_IndexedMapOfShape& fmap,
+ TopTools_IndexedMapOfShape& emap,
+ std::list< SMESH_subMesh* >& facesSM,
+ std::list< SMESH_subMesh* >& boundarySM);
+ // vertices
+ bool hasInternalVertexInSolid() const { return !_s2v.empty(); }
+ bool hasInternalVertexInSolid(int soID ) const { return _s2v.count(soID); }
+ const std::map<int,std::list<int> >& getSolidsWithVertices() const { return _s2v; }
+
+
+};
+
+//================================================================================
+/*!
+ * \brief It correctly initializes netgen library at constructor and
+ * correctly finishes using netgen library at destructor
+ */
+//================================================================================
+
+struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper
+{
+ nglib::Ng_Mesh * _ngMesh;
+ NETGENPlugin_NetgenLibWrapper();
+ ~NETGENPlugin_NetgenLibWrapper();
+ void setMesh( nglib::Ng_Mesh* mesh );
+};
+
#endif
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_NETGEN_2D.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_NETGEN_2D.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_NETGEN_2D3D.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_NETGEN_2D3D.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : idl implementation
// File : NETGENPlugin_NETGEN_2D3D_i.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : idl implementation
// File : NETGENPlugin_NETGEN_2D3D_i.hxx
// Author : Michael Sazonov (OCN)
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPlugin_NETGEN_2D_ONLY.cxx
// Author : Edward AGAPOV (OCC)
// Project : SALOME
//#include <meshtype.hpp>
namespace netgen {
extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
- /*extern*/ MeshingParameters mparam;
+ extern MeshingParameters mparam;
}
using namespace std;
using namespace netgen;
using namespace nglib;
+//#define DUMP_SEGMENTS
+
//=============================================================================
/*!
*
// Check wires and count nodes
// ----------------------------
int nbNodes = 0;
+ double totalLength = 0;
for ( int iW = 0; iW < wires.size(); ++iW )
{
StdMeshers_FaceSidePtr wire = wires[ iW ];
(new SMESH_ComputeError(COMPERR_BAD_INPUT_MESH,
SMESH_Comment("Unexpected nb of points on wire ") << iW
<< ": " << uvPtVec.size()<<" != "<<wire->NbPoints()));
- nbNodes += wire->NbSegments();
+ nbNodes += wire->NbPoints();
+ totalLength += wire->Length();
}
nodeVec.reserve( nbNodes );
// bb.Increase (bb.Diam()/10);
// ngMesh.SetLocalH (bb.PMin(), bb.PMax(), 0.5); // set grading
+ // map for nodes on vertices since they can be shared between wires
+ // ( issue 0020676, face_int_box.brep)
+ map<const SMDS_MeshNode*, int > node2ngID;
+
const int faceID = 1, solidID = 0;
- ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0));
+ if ( ngMesh.GetNFD() < 1 )
+ ngMesh.AddFaceDescriptor (FaceDescriptor(faceID, solidID, solidID, 0));
for ( int iW = 0; iW < wires.size(); ++iW )
{
StdMeshers_FaceSidePtr wire = wires[ iW ];
const vector<UVPtStruct>& uvPtVec = wire->GetUVPtStruct();
+ const int nbSegments = wire->NbPoints() - 1;
- int firstPointID = ngMesh.GetNP() + 1;
int edgeID = 1, posID = -2;
- bool isInternalEdge = false;
- for ( int i = 0; i < wire->NbSegments(); ++i ) // loop on segments
+ bool isInternalWire = false;
+ for ( int i = 0; i < nbSegments; ++i ) // loop on segments
{
// Add the first point of a segment
const SMDS_MeshNode * n = uvPtVec[ i ].node;
const int posShapeID = n->GetPosition()->GetShapeId();
+ bool onVertex = ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
// skip nodes on degenerated edges
if ( helper.IsDegenShape( posShapeID ) &&
helper.IsDegenShape( uvPtVec[ i+1 ].node->GetPosition()->GetShapeId() ))
continue;
- nodeVec.push_back( n );
-
- MeshPoint mp( Point<3> (n->X(), n->Y(), n->Z()) );
- ngMesh.AddPoint ( mp, 1, EDGEPOINT );
+ int ngID1 = ngMesh.GetNP() + 1, ngID2 = ngID1+1;
+ if ( onVertex )
+ ngID1 = node2ngID.insert( make_pair( n, ngID1 )).first->second;
+ if ( ngID1 > ngMesh.GetNP() )
+ {
+ MeshPoint mp( Point<3> (n->X(), n->Y(), n->Z()) );
+ ngMesh.AddPoint ( mp, 1, EDGEPOINT );
+ nodeVec.push_back( n );
+ }
+ else
+ {
+ ngID2 = ngMesh.GetNP() + 1;
+ if ( i > 0 ) // prev segment belongs to same wire
+ {
+ Segment& prevSeg = ngMesh.LineSegment( ngMesh.GetNSeg() );
+ prevSeg[1] = ngID1;
+ }
+ }
// Add the segment
Segment seg;
-#ifdef NETGEN_NEW
- seg.pnums[0] = ngMesh.GetNP(); // ng node id
- seg.pnums[1] = seg.pnums[0] + 1; // ng node id
-#else
- seg.p1 = ngMesh.GetNP(); // ng node id
- seg.p2 = seg.p1 + 1; // ng node id
-#endif
+ seg[0] = ngID1; // ng node id
+ seg[1] = ngID2; // ng node id
+
seg.edgenr = ngMesh.GetNSeg() + 1;// segment id
seg.si = faceID; // = geom.fmap.FindIndex (face);
seg.epgeominfo[ iEnd ].v = pnt.v;
// find out edge id and node parameter on edge
- bool onVertex = ( pnt.node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
+ onVertex = ( pnt.node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
if ( onVertex || posShapeID != posID )
{
// get edge id
const TopoDS_Edge& edge = wire->Edge( wire->EdgeIndex( normParam ));
edgeID = geom.emap.FindIndex( edge );
posID = posShapeID;
- isInternalEdge = ( edge.Orientation() == TopAbs_INTERNAL );
+ isInternalWire = ( edge.Orientation() == TopAbs_INTERNAL );
if ( onVertex ) // param on curve is different on each of two edges
seg.epgeominfo[ iEnd ].dist = helper.GetNodeU( edge, pnt.node );
}
ngMesh.AddSegment (seg);
-// cout << "Segment: " << seg.edgenr << endl
-// << "\tp1: " << seg.p1 << endl
-// << "\tp2: " << seg.p2 << endl
-// << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl
-// << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl
-// << "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl
-// << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl
-// << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl
-// << "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl;
-
- if ( isInternalEdge )
- {
-#ifdef NETGEN_NEW
- swap (seg.pnums[0], seg.pnums[1]);
-#else
- swap (seg.p1, seg.p2);
+#ifdef DUMP_SEGMENTS
+ cout << "Segment: " << seg.edgenr << endl
+ << "\tp1: " << seg[0] << endl
+ << "\tp2: " << seg[1] << endl
+ << "\tp0 param: " << seg.epgeominfo[ 0 ].dist << endl
+ << "\tp0 uv: " << seg.epgeominfo[ 0 ].u <<", "<< seg.epgeominfo[ 0 ].v << endl
+ << "\tp0 edge: " << seg.epgeominfo[ 0 ].edgenr << endl
+ << "\tp1 param: " << seg.epgeominfo[ 1 ].dist << endl
+ << "\tp1 uv: " << seg.epgeominfo[ 1 ].u <<", "<< seg.epgeominfo[ 1 ].v << endl
+ << "\tp1 edge: " << seg.epgeominfo[ 1 ].edgenr << endl;
#endif
+ if ( isInternalWire )
+ {
+ swap (seg[0], seg[1]);
swap( seg.epgeominfo[0], seg.epgeominfo[1] );
seg.edgenr = ngMesh.GetNSeg() + 1; // segment id
ngMesh.AddSegment (seg);
+#ifdef DUMP_SEGMENTS
+ cout << "Segment: " << seg.edgenr << endl << "\tis REVRESE of the previous one" << endl;
+#endif
}
} // loop on segments on a wire
// close chain of segments
- bool isClosedWire = ( wire->FirstVertex().IsSame( wire->LastVertex() ));
- if ( isClosedWire )
+ if ( nbSegments > 0 )
{
- Segment& seg = ngMesh.LineSegment( ngMesh.GetNSeg() );
-#ifdef NETGEN_NEW
- seg.pnums[1] = firstPointID;
-#else
- seg.p2 = firstPointID;
-#endif
- }
- else // INTERNAL wire (Issue 0020676)
- {
- const SMDS_MeshNode * n = uvPtVec.back().node;
- nodeVec.push_back( n );
-
- MeshPoint mp( Point<3> (n->X(), n->Y(), n->Z()) );
- ngMesh.AddPoint ( mp, 1, EDGEPOINT );
+ Segment& lastSeg = ngMesh.LineSegment( ngMesh.GetNSeg() - int( isInternalWire));
+ const SMDS_MeshNode * lastNode = uvPtVec.back().node;
+ lastSeg[1] = node2ngID.insert( make_pair( lastNode, lastSeg[1] )).first->second;
+ if ( lastSeg[1] > ngMesh.GetNP() )
+ {
+ MeshPoint mp( Point<3> (lastNode->X(), lastNode->Y(), lastNode->Z()) );
+ ngMesh.AddPoint ( mp, 1, EDGEPOINT );
+ nodeVec.push_back( lastNode );
+ }
+ if ( isInternalWire )
+ {
+ Segment& realLastSeg = ngMesh.LineSegment( ngMesh.GetNSeg() );
+ realLastSeg[0] = lastSeg[1];
+ }
}
} // loop on wires of a face
- ngMesh.CalcSurfacesOfNode();
+ // add a segment instead of internal vertex
+ NETGENPlugin_Internals intShapes( *helper.GetMesh(), helper.GetSubShape(), /*is3D=*/false );
+ NETGENPlugin_Mesher::addIntVerticesInFaces( geom, ngMesh, nodeVec, intShapes );
+
+ ngMesh.CalcSurfacesOfNode();
return TError();
}
// Make input netgen mesh
// -------------------------
- Ng_Init();
- netgen::Mesh * ngMesh = new netgen::Mesh ();
+ NETGENPlugin_NetgenLibWrapper ngLib;
+ netgen::Mesh * ngMesh = (netgen::Mesh*) ngLib._ngMesh;
netgen::OCCGeometry occgeo;
NETGENPlugin_Mesher::PrepareOCCgeometry( occgeo, F, aMesh );
vector< const SMDS_MeshNode* > nodeVec;
problem = AddSegmentsToMesh( *ngMesh, occgeo, wires, helper, nodeVec );
- if ( problem && !problem->IsOK() ) {
- delete ngMesh; Ng_Exit();
+ if ( problem && !problem->IsOK() )
return error( problem );
- }
// --------------------
// compute edge length
face = helper.AddFace(nodes[0],nodes[1],nodes[2],nodes[3]);
}
- Ng_DeleteMesh((nglib::Ng_Mesh*)ngMesh);
- Ng_Exit();
-
- NETGENPlugin_Mesher::RemoveTmpFiles();
-
return !err;
}
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// File : NETGENPlugin_NETGEN_2D_ONLY.hxx
// Project : SALOME
// Author : Edward AGAPOV (OCC)
#include "SMESH_2D_Algo.hxx"
#include "SMESH_Mesh.hxx"
-/*#define OCCGEOMETRY
-#include <occgeom.hpp>
-#include <meshing.hpp>//amv*/
-
class StdMeshers_MaxElementArea;
class StdMeshers_LengthFromEdges;
class StdMeshers_QuadranglePreference;
-//class NETGENPlugin_Hypothesis;
-
-/*namespace netgen {
- class OCCGeometry;
-}*/
-/*namespace netgen {
- class OCCGeometry;
- extern int OCCGenerateMesh (OCCGeometry&, Mesh*&, int, int, char*);
- extern MeshingParameters mparam;
-}*/
-
-//using namespace netgen;
/*!
* \brief Mesher generating 2D elements on a geometrical face taking
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : NETGENPlugin_NETGEN_2D_ONLY_i.cxx
// Author : Edward AGAPOV (OCC)
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : NETGENPlugin_NETGEN_2D_ONLY_i.cxx
// Author : Edward AGAPOV (OCC)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : idl implementation
// File : NETGENPlugin_NETGEN_2D_i.cxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : idl implementation
// File : NETGENPlugin_NETGEN_2D_i.hxx
// Author : Michael Sazonov (OCN)
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
//=============================================================================
// File : NETGENPlugin_NETGEN_3D.cxx
// Moved here from SMESH_NETGEN_3D.cxx
#include "SMESH_MeshEditor.hxx"
#include "StdMeshers_QuadToTriaAdaptor.hxx"
+#include <BRepGProp.hxx>
#include <BRep_Tool.hxx>
#include <GProp_GProps.hxx>
-#include <BRepGProp.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopoDS.hxx>
#include <Standard_Failure.hxx>
Netgen include files
*/
+#define OCCGEOMETRY
+#include <occgeom.hpp>
namespace nglib {
#include <nglib.h>
}
*/
//=============================================================================
-bool NETGENPlugin_NETGEN_3D::CheckHypothesis
- (SMESH_Mesh& aMesh,
- const TopoDS_Shape& aShape,
- SMESH_Hypothesis::Hypothesis_Status& aStatus)
+bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ Hypothesis_Status& aStatus)
{
MESSAGE("NETGENPlugin_NETGEN_3D::CheckHypothesis");
SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
- const int invalid_ID = -1;
+ SMESH_MesherHelper helper(aMesh);
+ bool _quadraticMesh = helper.IsQuadraticSubMesh(aShape);
+ helper.SetElementsOnShape( true );
- SMESH::Controls::Area areaControl;
- SMESH::Controls::TSequenceOfXYZ nodesCoords;
+ int Netgen_NbOfNodes = 0;
+ int Netgen_param2ndOrder = 0;
+ double Netgen_paramFine = 1.;
+ double Netgen_paramSize = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. );
- // -------------------------------------------------------------------
- // get triangles on aShell and make a map of nodes to Netgen node IDs
- // -------------------------------------------------------------------
+ double Netgen_point[3];
+ int Netgen_triangle[3];
+ int Netgen_tetrahedron[4];
- SMESH_MesherHelper helper(aMesh);
- SMESH_MesherHelper* myTool = &helper;
- bool _quadraticMesh = myTool->IsQuadraticSubMesh(aShape);
+ NETGENPlugin_NetgenLibWrapper ngLib;
+ Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
- typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap;
- TNodeToIDMap nodeToNetgenID;
- list< const SMDS_MeshElement* > triangles;
- list< bool > isReversed; // orientation of triangles
+ // vector of nodes in which node index == netgen ID
+ vector< const SMDS_MeshNode* > nodeVec;
+ {
+ const int invalid_ID = -1;
- TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType();
- bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID );
+ SMESH::Controls::Area areaControl;
+ SMESH::Controls::TSequenceOfXYZ nodesCoords;
- // for the degeneraged edge: ignore all but one node on it;
- // map storing ids of degen edges and vertices and their netgen id:
- map< int, int* > degenShapeIdToPtrNgId;
- map< int, int* >::iterator shId_ngId;
- list< int > degenNgIds;
+ // maps nodes to ng ID
+ typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap;
+ typedef TNodeToIDMap::value_type TN2ID;
+ TNodeToIDMap nodeToNetgenID;
- StdMeshers_QuadToTriaAdaptor Adaptor;
- Adaptor.Compute(aMesh,aShape);
+ // find internal shapes
+ NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true );
- for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next())
- {
- const TopoDS_Shape& aShapeFace = exp.Current();
- const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace );
- if ( aSubMeshDSFace )
+ // ---------------------------------
+ // Feed the Netgen with surface mesh
+ // ---------------------------------
+
+ TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType();
+ bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID );
+
+ StdMeshers_QuadToTriaAdaptor Adaptor;
+ if ( aMesh.NbQuadrangles() > 0 )
+ Adaptor.Compute(aMesh,aShape);
+
+ for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next())
{
+ const TopoDS_Shape& aShapeFace = exFa.Current();
+ int faceID = meshDS->ShapeToIndex( aShapeFace );
+ bool isInternalFace = internals.isInternalShape( faceID );
bool isRev = false;
- if ( checkReverse && helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 )
+ if ( checkReverse && !isInternalFace &&
+ helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 )
// IsReversedSubMesh() can work wrong on strongly curved faces,
// so we use it as less as possible
isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS );
+ const SMESHDS_SubMesh * aSubMeshDSFace = meshDS->MeshElements( aShapeFace );
+ if ( !aSubMeshDSFace ) continue;
SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
- while ( iteratorElem->more() ) // loop on elements on a face
+ while ( iteratorElem->more() ) // loop on elements on a geom face
{
- // check element
+ // check mesh face
const SMDS_MeshElement* elem = iteratorElem->next();
if ( !elem )
return error( COMPERR_BAD_INPUT_MESH, "Null element encounters");
+ vector< const SMDS_MeshElement* > trias;
bool isTraingle = ( elem->NbNodes() == ( elem->IsQuadratic() ? 6 : 3 ));
- if ( !isTraingle ) {
- // using adaptor
+ if ( !isTraingle )
+ {
+ // use adaptor to convert quadrangle face into triangles
const list<const SMDS_FaceOfNodes*>* faces = Adaptor.GetTriangles(elem);
- if(faces==0) {
+ if(faces==0)
return error( COMPERR_BAD_INPUT_MESH,
SMESH_Comment("No triangles in adaptor for element ")<<elem->GetID());
- }
- list<const SMDS_FaceOfNodes*>::const_iterator itf = faces->begin();
- for(; itf!=faces->end(); itf++ ) {
- triangles.push_back( (*itf) );
- isReversed.push_back( isRev );
- // put triange's nodes to nodeToNetgenID map
- SMDS_ElemIteratorPtr triangleNodesIt = (*itf)->nodesIterator();
- while ( triangleNodesIt->more() ) {
- const SMDS_MeshNode * node =
- static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
- if(myTool->IsMedium(node))
- continue;
- nodeToNetgenID.insert( make_pair( node, invalid_ID ));
+ trias.assign( faces->begin(), faces->end() );
+ }
+ else
+ {
+ trias.push_back( elem );
+ }
+ // Add nodes of triangles and triangles them-selves to netgen mesh
+
+ for ( int i = 0; i < trias.size(); ++i )
+ {
+ // add three nodes of triangle
+ bool hasDegen = false;
+ for ( int iN = 0; iN < 3; ++iN )
+ {
+ const SMDS_MeshNode* node = trias[i]->GetNode( iN );
+ int shapeID = node->GetPosition()->GetShapeId();
+ if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE &&
+ helper.IsDegenShape( shapeID ))
+ {
+ // ignore all nodes on degeneraged edge and use node on its vertex instead
+ TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value();
+ node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS );
+ hasDegen = true;
+ }
+ int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second;
+ if ( ngID == invalid_ID )
+ {
+ ngID = ++Netgen_NbOfNodes;
+ Netgen_point [ 0 ] = node->X();
+ Netgen_point [ 1 ] = node->Y();
+ Netgen_point [ 2 ] = node->Z();
+ Ng_AddPoint(Netgen_mesh, Netgen_point);
}
+ Netgen_triangle[ isRev ? 2-iN : iN ] = ngID;
}
- }
- else {
- // keep a triangle
- triangles.push_back( elem );
- isReversed.push_back( isRev );
- // put elem nodes to nodeToNetgenID map
- SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator();
- while ( triangleNodesIt->more() ) {
- const SMDS_MeshNode * node =
- static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
- if(myTool->IsMedium(node))
- continue;
- nodeToNetgenID.insert( make_pair( node, invalid_ID ));
+ // add triangle
+ if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] ||
+ Netgen_triangle[0] == Netgen_triangle[2] ||
+ Netgen_triangle[2] == Netgen_triangle[1] ))
+ continue;
+
+ Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
+
+ if ( isInternalFace && isTraingle )
+ {
+ swap( Netgen_triangle[1], Netgen_triangle[2] );
+ Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
}
}
#ifdef _DEBUG_
MESSAGE( "Warning: Degenerated " << elem );
}
#endif
- }
- // look for degeneraged edges and vetices
- for (TopExp_Explorer expE(aShapeFace,TopAbs_EDGE);expE.More();expE.Next())
- {
- TopoDS_Edge aShapeEdge = TopoDS::Edge( expE.Current() );
- if ( BRep_Tool::Degenerated( aShapeEdge ))
- {
- degenNgIds.push_back( invalid_ID );
- int* ptrIdOnEdge = & degenNgIds.back();
- // remember edge id
- int edgeID = meshDS->ShapeToIndex( aShapeEdge );
- degenShapeIdToPtrNgId.insert( make_pair( edgeID, ptrIdOnEdge ));
- // remember vertex id
- int vertexID = meshDS->ShapeToIndex( TopExp::FirstVertex( aShapeEdge ));
- degenShapeIdToPtrNgId.insert( make_pair( vertexID, ptrIdOnEdge ));
- }
- }
- }
- }
- // ---------------------------------
- // Feed the Netgen with surface mesh
- // ---------------------------------
+ } // loop on elements on a face
+ } // loop on faces of a SOLID or SHELL
- int Netgen_NbOfNodes = 0;
- int Netgen_param2ndOrder = 0;
- double Netgen_paramFine = 1.;
- double Netgen_paramSize = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. );
-
- double Netgen_point[3];
- int Netgen_triangle[3];
- int Netgen_tetrahedron[4];
-
- Ng_Init();
-
- Ng_Mesh * Netgen_mesh = Ng_NewMesh();
-
- // set nodes and remember thier netgen IDs
- bool isDegen = false, hasDegen = !degenShapeIdToPtrNgId.empty();
- TNodeToIDMap::iterator n_id = nodeToNetgenID.begin();
- for ( ; n_id != nodeToNetgenID.end(); ++n_id )
- {
- const SMDS_MeshNode* node = n_id->first;
-
- // ignore nodes on degenerated edge
- if ( hasDegen ) {
- int shapeId = node->GetPosition()->GetShapeId();
- shId_ngId = degenShapeIdToPtrNgId.find( shapeId );
- isDegen = ( shId_ngId != degenShapeIdToPtrNgId.end() );
- if ( isDegen && *(shId_ngId->second) != invalid_ID ) {
- n_id->second = *(shId_ngId->second);
- continue;
- }
- }
- Netgen_point [ 0 ] = node->X();
- Netgen_point [ 1 ] = node->Y();
- Netgen_point [ 2 ] = node->Z();
- Ng_AddPoint(Netgen_mesh, Netgen_point);
- n_id->second = ++Netgen_NbOfNodes; // set netgen ID
-
- if ( isDegen ) // all nodes on a degen edge get one netgen ID
- *(shId_ngId->second) = n_id->second;
- }
+ // insert old nodes into nodeVec
+ nodeVec.resize( nodeToNetgenID.size() + 1, 0 );
+ TNodeToIDMap::iterator n_id = nodeToNetgenID.begin();
+ for ( ; n_id != nodeToNetgenID.end(); ++n_id )
+ nodeVec[ n_id->second ] = n_id->first;
+ nodeToNetgenID.clear();
- // set triangles
- list< const SMDS_MeshElement* >::iterator tria = triangles.begin();
- list< bool >::iterator reverse = isReversed.begin();
- for ( ; tria != triangles.end(); ++tria, ++reverse )
- {
- int i = 0;
- SMDS_ElemIteratorPtr triangleNodesIt = (*tria)->nodesIterator();
- while ( triangleNodesIt->more() ) {
- const SMDS_MeshNode * node =
- static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
- if(myTool->IsMedium(node))
- continue;
- Netgen_triangle[ *reverse ? 2 - i : i ] = nodeToNetgenID[ node ];
- ++i;
- }
- if ( !hasDegen ||
- // ignore degenerated triangles, they have 2 or 3 same ids
- (Netgen_triangle[0] != Netgen_triangle[1] &&
- Netgen_triangle[0] != Netgen_triangle[2] &&
- Netgen_triangle[2] != Netgen_triangle[1] ))
+ if ( internals.hasInternalVertexInSolid() )
{
- Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle);
+ netgen::OCCGeometry occgeo;
+ NETGENPlugin_Mesher::addIntVerticesInSolids( occgeo,
+ (netgen::Mesh&) *Netgen_mesh,
+ nodeVec,
+ internals);
+ Netgen_NbOfNodes = Ng_GetNP(Netgen_mesh);
}
}
Ng_Meshing_Parameters Netgen_param;
Netgen_param.secondorder = Netgen_param2ndOrder;
- Netgen_param.fineness = Netgen_paramFine;
- Netgen_param.maxh = Netgen_paramSize;
+ Netgen_param.fineness = Netgen_paramFine;
+ Netgen_param.maxh = Netgen_paramSize;
Ng_Result status;
}
int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh);
-
- int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
+ int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh);
MESSAGE("End of Volume Mesh Generation. status=" << status <<
", nb new nodes: " << Netgen_NbOfNodesNew - Netgen_NbOfNodes <<
// Feed back the SMESHDS with the generated Nodes and Volume Elements
// -------------------------------------------------------------------
+ if ( status == NG_VOLUME_FAILURE )
+ {
+ SMESH_ComputeErrorPtr err = NETGENPlugin_Mesher::readErrors(nodeVec);
+ if ( err && !err->myBadElements.empty() )
+ error( err );
+ }
+
bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built
if ( isOK )
{
- // vector of nodes in which node index == netgen ID
- vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 );
- // insert old nodes into nodeVec
- for ( n_id = nodeToNetgenID.begin(); n_id != nodeToNetgenID.end(); ++n_id ) {
- nodeVec.at( n_id->second ) = n_id->first;
- }
// create and insert new nodes into nodeVec
+ nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 );
int nodeIndex = Netgen_NbOfNodes + 1;
- int shapeID = meshDS->ShapeToIndex( aShape );
for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex )
{
Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point );
- SMDS_MeshNode * node = meshDS->AddNode(Netgen_point[0],
- Netgen_point[1],
- Netgen_point[2]);
- meshDS->SetNodeInVolume(node, shapeID);
- nodeVec.at(nodeIndex) = node;
+ nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], Netgen_point[1], Netgen_point[2]);
}
// create tetrahedrons
for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex )
{
Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron);
- SMDS_MeshVolume * elt = myTool->AddVolume (nodeVec.at( Netgen_tetrahedron[0] ),
- nodeVec.at( Netgen_tetrahedron[1] ),
- nodeVec.at( Netgen_tetrahedron[2] ),
- nodeVec.at( Netgen_tetrahedron[3] ));
- meshDS->SetMeshElementOnShape(elt, shapeID );
+ helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ),
+ nodeVec.at( Netgen_tetrahedron[1] ),
+ nodeVec.at( Netgen_tetrahedron[2] ),
+ nodeVec.at( Netgen_tetrahedron[3] ));
}
}
- Ng_DeleteMesh(Netgen_mesh);
- Ng_Exit();
-
- NETGENPlugin_Mesher::RemoveTmpFiles();
-
return (status == NG_OK);
}
-bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
+//================================================================================
+/*!
+ * \brief Compute tetrahedral mesh from 2D mesh without geometry
+ */
+//================================================================================
+
+bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh,
SMESH_MesherHelper* aHelper)
{
MESSAGE("NETGENPlugin_NETGEN_3D::Compute with maxElmentsize = " << _maxElementVolume);
while( fIt->more()) sortedFaces.insert( fIt->next() );
TIDSortedElemSet::iterator itFace = sortedFaces.begin(), fEnd = sortedFaces.end();
- for ( ; itFace != fEnd; ++itFace ) {
+ for ( ; itFace != fEnd; ++itFace )
+ {
// check element
const SMDS_MeshElement* elem = *itFace;
if ( !elem )
return error( COMPERR_BAD_INPUT_MESH, "Null element encounters");
+
+ vector< const SMDS_MeshElement* > trias;
bool isTraingle = ( elem->NbNodes() == ( elem->IsQuadratic() ? 6 : 3 ));
if ( !isTraingle ) {
// using adaptor
const list<const SMDS_FaceOfNodes*>* faces = Adaptor.GetTriangles(elem);
- if(faces==0) {
+ if(faces==0)
continue; // Issue 0020682. There already can be 3d mesh
- }
- list<const SMDS_FaceOfNodes*>::const_iterator itf = faces->begin();
- for(; itf!=faces->end(); itf++ ) {
- triangles.push_back( (*itf) );
- // put triange's nodes to nodeToNetgenID map
- SMDS_ElemIteratorPtr triangleNodesIt = (*itf)->nodesIterator();
- while ( triangleNodesIt->more() ) {
- const SMDS_MeshNode * node =
- static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
- if(aHelper->IsMedium(node))
- continue;
- nodeToNetgenID.insert( make_pair( node, invalid_ID ));
- }
- }
+ trias.assign( faces->begin(), faces->end() );
}
else {
- // keep a triangle
- triangles.push_back( elem );
- // put elem nodes to nodeToNetgenID map
- SMDS_ElemIteratorPtr triangleNodesIt = elem->nodesIterator();
- while ( triangleNodesIt->more() ) {
- const SMDS_MeshNode * node =
- static_cast<const SMDS_MeshNode *>(triangleNodesIt->next());
- if(aHelper->IsMedium(node))
- continue;
+ trias.push_back( elem );
+ }
+ for ( int i = 0; i < trias.size(); ++i )
+ {
+ triangles.push_back( trias[i] );
+ for ( int iN = 0; iN < 3; ++iN )
+ {
+ const SMDS_MeshNode* node = trias[i]->GetNode( iN );
+ // put elem nodes to nodeToNetgenID map
nodeToNetgenID.insert( make_pair( node, invalid_ID ));
}
}
int Netgen_triangle[3];
int Netgen_tetrahedron[4];
- Ng_Init();
-
- Ng_Mesh * Netgen_mesh = Ng_NewMesh();
+ NETGENPlugin_NetgenLibWrapper ngLib;
+ Ng_Mesh * Netgen_mesh = ngLib._ngMesh;
- // set nodes and remember thier netgen IDs
+ // set nodes and remember thier netgen IDs
TNodeToIDMap::iterator n_id = nodeToNetgenID.begin();
for ( ; n_id != nodeToNetgenID.end(); ++n_id )
}
}
- Ng_DeleteMesh(Netgen_mesh);
- Ng_Exit();
-
- NETGENPlugin_Mesher::RemoveTmpFiles();
-
return (status == NG_OK);
}
{
int nbtri = 0, nbqua = 0;
double fullArea = 0.0;
- for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
- TopoDS_Face F = TopoDS::Face( exp.Current() );
+ for (TopExp_Explorer expF(aShape, TopAbs_FACE); expF.More(); expF.Next()) {
+ TopoDS_Face F = TopoDS::Face( expF.Current() );
SMESH_subMesh *sm = aMesh.GetSubMesh(F);
MapShapeNbElemsItr anIt = aResMap.find(sm);
if( anIt==aResMap.end() ) {
bool IsQuadratic = false;
bool IsFirst = true;
TopTools_MapOfShape tmpMap;
- for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) {
- TopoDS_Edge E = TopoDS::Edge(exp.Current());
+ for (TopExp_Explorer expF(aShape, TopAbs_EDGE); expF.More(); expF.Next()) {
+ TopoDS_Edge E = TopoDS::Edge(expF.Current());
if( tmpMap.Contains(E) )
continue;
tmpMap.Add(E);
- SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(expF.Current());
MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
if( anIt==aResMap.end() ) {
SMESH_ComputeErrorPtr& smError = aSubMesh->GetComputeError();
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
//=============================================================================
// File : NETGENPlugin_NETGEN_3D.hxx
// Moved here from SMESH_NETGEN_3D.hxx
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : NETGENPlugin_NETGEN_3D_i.cxx
// Moved here from SMESH_NETGEN_3D_i.cxx
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : NETGENPlugin_NETGEN_3D_i.hxx
// Moved here from SMESH_NETGEN_3D_i.hxx
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_2D.cxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_2D.hxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_2D_i.cxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_2D_i.hxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_3D.cxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_3D.hxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_3D_i.cxx
// Author : Edward AGAPOV
-// 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
+// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// NETGENPlugin : C++ implementation
// File : NETGENPlugin_SimpleHypothesis_3D_i.hxx
// Author : Edward AGAPOV
-// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+// 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
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
+
// SMESH NETGENPlugin : implementaion of SMESH idl descriptions
// File : NETGENPlugin.cxx
// Author : Julia DOROVSKIKH