53539: 0D Element

1) Extract SMESHUtils/SMESH_ControlPnt.* from Hexotic
2) Minor doc changes
3) fix  53539: 0D Element (SMDS_MeshCell.hxx, SMESHGUI_AddMeshElementDlg.cxx)
4) Regressions
- bugs_06/G9 ( SMESH_DumpPython.cxx, SMESH_PythonDump.hxx )
- bugs_13/N8 ( StdMeshers_Regular_1D.cxx )
This commit is contained in:
eap 2016-08-24 17:04:22 +03:00
parent 7c69e00bac
commit 83b0c984cc
24 changed files with 597 additions and 142 deletions

View File

@ -1,16 +1,10 @@
# Add Node # Add Node
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
mesh = smesh.Mesh() mesh = smesh.Mesh()

View File

@ -1,16 +1,10 @@
# Add 0D Element # Add 0D Element
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
mesh = smesh.Mesh() mesh = smesh.Mesh()

View File

@ -3,14 +3,13 @@
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy) geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
# create a geometry # create a geometry

View File

@ -4,14 +4,10 @@ import math
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
# create an empty mesh structure # create an empty mesh structure

View File

@ -3,14 +3,9 @@
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
import math import math
@ -50,7 +45,7 @@ for i in range(5):
pass pass
# Create a polyhedral volume (12-hedron with pentagonal faces) # Create a polyhedral volume (12-hedron with pentagonal faces)
mesh.GetMeshEditor().AddPolyhedralVolume([dd[0], dd[1], dd[2], dd[3], dd[4], # top mesh.AddPolyhedralVolume([dd[0], dd[1], dd[2], dd[3], dd[4], # top
dd[0], cc[0], bb[1], cc[1], dd[1], # - dd[0], cc[0], bb[1], cc[1], dd[1], # -
dd[1], cc[1], bb[2], cc[2], dd[2], # - dd[1], cc[1], bb[2], cc[2], dd[2], # -
dd[2], cc[2], bb[3], cc[3], dd[3], # - below top dd[2], cc[2], bb[3], cc[3], dd[3], # - below top
@ -64,4 +59,5 @@ mesh.GetMeshEditor().AddPolyhedralVolume([dd[0], dd[1], dd[2], dd[3], dd[4], #
aa[0], aa[1], aa[2], aa[3], aa[4]], # bottom aa[0], aa[1], aa[2], aa[3], aa[4]], # bottom
[5,5,5,5,5,5,5,5,5,5,5,5]) [5,5,5,5,5,5,5,5,5,5,5,5])
if salome.sg.hasDesktop():
salome.sg.updateObjBrowser(1) salome.sg.updateObjBrowser(1)

View File

@ -3,14 +3,13 @@
import salome import salome
salome.salome_init() salome.salome_init()
import GEOM
from salome.geom import geomBuilder from salome.geom import geomBuilder
geompy = geomBuilder.New(salome.myStudy) geompy = geomBuilder.New(salome.myStudy)
import SMESH, SALOMEDS import SMESH, SALOMEDS
from salome.smesh import smeshBuilder from salome.smesh import smeshBuilder
smesh = smeshBuilder.New(salome.myStudy) smesh = smeshBuilder.New(salome.myStudy)
import salome_notebook
box = geompy.MakeBoxDXDYDZ(200, 200, 200) box = geompy.MakeBoxDXDYDZ(200, 200, 200)
@ -20,7 +19,7 @@ mesh.Segment().AutomaticLength(0.1)
mesh.Quadrangle() mesh.Quadrangle()
mesh.Compute() mesh.Compute()
# find node at (0,0,0) # find node at (0,0,0) which is located on a geom vertex
node000 = None node000 = None
for vId in geompy.SubShapeAllIDs( box, geompy.ShapeType["VERTEX"]): for vId in geompy.SubShapeAllIDs( box, geompy.ShapeType["VERTEX"]):
if node000: break if node000: break
@ -36,7 +35,7 @@ for vId in geompy.SubShapeAllIDs( box, geompy.ShapeType["VERTEX"]):
if not node000: if not node000:
raise "node000 not found" raise "node000 not found"
# find node000 using the tested function # find node000 using a dedicated function
n = mesh.FindNodeClosestTo( -1,-1,-1 ) n = mesh.FindNodeClosestTo( -1,-1,-1 )
if not n == node000: if not n == node000:
raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 ) raise "FindNodeClosestTo() returns " + str( n ) + " != " + str( node000 )

View File

@ -2,7 +2,8 @@
\page display_mode_page Display Mode \page display_mode_page Display Mode
\n By default your objects are represented as set in \b Preferences. \n By default your objects are represented as set in
\ref mesh_preferences_page "Preferences".
\n However, right-clicking on the mesh in the <b>Object Browser</b>, \n However, right-clicking on the mesh in the <b>Object Browser</b>,
and selecting <b>Display Mode</b>, you can display your mesh as: and selecting <b>Display Mode</b>, you can display your mesh as:

View File

@ -41,17 +41,20 @@ group as a whole mesh.
If you try to export a group, the warning will be shown: If you try to export a group, the warning will be shown:
\image html meshexportgroupwarning.png \image html meshexportgroupwarning.png
<ul> <ul>
<li><b>Don't show this warning anymore</b> check-box specifies show or <li><b>Don't show this warning anymore</b> check-box allows to
not the warning. If checked, the warning will not be shown anymore in switch off the warning. You can re-activate the warning in
the similar situation </li> \ref group_export_warning_pref "Preferences".</li>
</ul> </ul>
There are additional parameters available at export to MED and SAUV format files. There are additional parameters available at export to MED and SAUV format files.
<ul> <ul>
<li><b>Automatically create groups</b> check-box specifies whether to <li>
\anchor export_auto_groups
<b>Automatically create groups</b> check-box specifies whether to
create groups of all mesh entities of available dimensions or create groups of all mesh entities of available dimensions or
not. If checked, the created groups have names like "Group_On_All_Nodes", not. The created groups have names like "Group_On_All_Nodes",
"Group_On_All_Faces", etc.</li> "Group_On_All_Faces", etc. A default state of this check-box can be
set in \ref export_auto_groups_pref "Preferences". </li>
<li><b>Automatically define space dimension</b> check-box specifies <li><b>Automatically define space dimension</b> check-box specifies
whether to define space dimension for export by mesh configuration whether to define space dimension for export by mesh configuration
or not. Usually the mesh is exported as a mesh in 3D space, just as or not. Usually the mesh is exported as a mesh in 3D space, just as

View File

@ -10,15 +10,15 @@ or in later sessions with this module according to the preferences.
\image html pref21.png \image html pref21.png
- <b>Automatic Update</b> - <b>Automatic Update</b>
- If you toggle <b>Automatic Update</b> checkbox, the model in your - <b>Automatic Update</b> - if activated, the mesh in your
viewer will be automatically updated when you make changes in it, depending on viewer will be automatically updated after it's computation, depending on
values of additional preferences specified below. values of additional preferences specified below.
- <b>Size limit (elements)</b> - allows specifying the maximum - <b>Size limit (elements)</b> - allows specifying the maximum
number of elements in the resulting mesh for which the automatic updating number of elements in the resulting mesh for which the automatic updating
of the presentation is performed. This option affects only of the presentation is performed. This option affects only
<b>Compute</b> operation. Zero value means "no limit". Default value \ref compute_anchor "Compute" operation. Zero value means "no
is 500 000 mesh elements. limit". Default value is 500 000 mesh elements.
- <b>Incremental limit check</b> - when this control is switched on, - <b>Incremental limit check</b> - if activated,
the mesh size limit check is not applied to the total number of the mesh size limit check is not applied to the total number of
elements in the resulting mesh, it is applied iteratively to each entity type elements in the resulting mesh, it is applied iteratively to each entity type
in the following order: 0D elements, edges, faces, volumes, balls. in the following order: 0D elements, edges, faces, volumes, balls.
@ -28,32 +28,40 @@ or in later sessions with this module according to the preferences.
this type are shown, otherwise the user is warned that some entities are not shown. this type are shown, otherwise the user is warned that some entities are not shown.
- <b>Quality Controls</b> - <b>Quality Controls</b>
- If you toggle <b>Display entity</b>, both faces and edges of an - <b>Display entity</b> - if activated, only currently
object will be displayed in the viewer by default. \ref quality_page "controlled" entities are displayed in the
- If you toggle <b>Use precision</b> checkbox, you can display numbers in viewer and other entities are temporarily hidden. For example if you
<b>Quality Control</b> diagrams at the necessary level of precision. activate \ref length_page "Length" quality control, which controls
- <b>Number of digits after point</b> - defines precision for the length of mesh segments, then only mesh segments are
<b>Quality Controls</b>. By default, numbers in <b>Quality Control</b> displayed and faces and volumes are hidden.
diagrams are presented as integers. - <b>Use precision</b> - if activated, all quality controls
- <b>Double nodes tolerance</b> defines the maximal distance between two will be computed at precision defined by <b>Number of digits after
mesh nodes, at which they are considered coincident by <b>Double nodes</b> point</b> - as integers by default.
quality control. - <b>Double nodes tolerance</b> - defines the maximal distance between two
mesh nodes, at which they are considered coincident by
\ref double_nodes_control_page "Double nodes" quality control.
- <b>Display mode</b> - <b>Display mode</b>
- <b>Default display mode</b> - allows to set Wireframe, Shading, Nodes or Shrink - <b>Default display mode</b> - allows to set Wireframe, Shading, Nodes or Shrink
presentation mode as default. \ref display_mode_page "presentation mode" as default.
\anchor quadratic_2d_mode_pref
- <b>Representation of the 2D quadratic elements</b> - <b>Representation of the 2D quadratic elements</b>
- <b>Default mode of the 2D quadratic elements</b> combo-box - allows - <b>Default mode of the 2D quadratic elements</b> - allows to
to select lines or arcs for representation of quadratic elements as default. select either \a Lines or \a Arcs as a default
\ref quadratic_2d_mode "representation" of 1D and 2D
\ref adding_quadratic_elements_page "quadratic elements".
- <b>Maximum Angle</b> - maximum deviation angle used by the - <b>Maximum Angle</b> - maximum deviation angle used by the
application to build arcs. application to build arcs.
- <b>Mesh export</b> - <b>Mesh export</b>
- If you toggle <b>Automatically create groups for MED export</b> check-box, \anchor export_auto_groups_pref
this operation will be carried out automatically. - <b>Automatically create groups for MED export</b> - defines a
- <b>Show warning when exporting group</b> check-box - allows defining the default state of a corresponding check-box in \ref export_auto_groups
behavior of the warning when exporting a group. "MED Export" dialog.
\anchor group_export_warning_pref
- <b>Show warning when exporting group</b> - if activated, a warning is
displayed when exporting a group.
- <b>Mesh computation</b> - <b>Mesh computation</b>
- <b>Show a computation result notification</b> combo-box allows to - <b>Show a computation result notification</b> combo-box allows to

View File

@ -75,10 +75,6 @@
<h3>Removing Orphan Nodes</h3> <h3>Removing Orphan Nodes</h3>
\tui_script{modifying_meshes_ex13.py} \tui_script{modifying_meshes_ex13.py}
<br>
\section tui_renumbering_nodes_and_elements Renumbering Nodes and Elements
\tui_script{modifying_meshes_ex14.py}
<br> <br>
\section tui_moving_nodes Moving Nodes \section tui_moving_nodes Moving Nodes
\tui_script{modifying_meshes_ex15.py} \tui_script{modifying_meshes_ex15.py}

View File

@ -37,8 +37,12 @@ viewer.</li>
Wireframe, Shading and Nodes presentation.</li> Wireframe, Shading and Nodes presentation.</li>
<li>\subpage display_entity_page "Display Entity" - allows to display <li>\subpage display_entity_page "Display Entity" - allows to display
entities by types (Faces, Edges, Volumes etc.).</li> entities by types (Faces, Edges, Volumes etc.).</li>
\anchor quadratic_2d_mode
<li><b>2D Quadratic</b> - allows to select between the representation <li><b>2D Quadratic</b> - allows to select between the representation
of quadratic edges as broken <b>lines</b> or as <b>arcs</b></li> of quadratic edges as broken \b lines or as \b arcs. A default
representation can be set in \ref quadratic_2d_mode_pref "Preferences".
Arc representation applies to 1D and 2D elements only.
</li>
<li><b>Orientation of faces</b> - shows vectors of orientation of <li><b>Orientation of faces</b> - shows vectors of orientation of
faces of the selected mesh. The orientation vector is shown for each 2D mesh element faces of the selected mesh. The orientation vector is shown for each 2D mesh element
and for each free face of a 3D mesh element. the vector direction is calculated by and for each free face of a 3D mesh element. the vector direction is calculated by

View File

@ -34,6 +34,8 @@
#include "utilities.h" #include "utilities.h"
using SMESHUtils::ControlPnt;
extern "C" extern "C"
{ {
#include "libmesh5.h" #include "libmesh5.h"
@ -80,29 +82,6 @@ extern "C"
}}}} }}}}
Control_Pnt::Control_Pnt(): gp_Pnt()
{
size=0;
}
Control_Pnt::Control_Pnt( const gp_Pnt& aPnt,
double theSize): gp_Pnt( aPnt )
{
size=theSize;
}
Control_Pnt::Control_Pnt(double theX,
double theY,
double theZ): gp_Pnt(theX, theY, theZ)
{
size=0;
}
Control_Pnt::Control_Pnt(double theX,
double theY,
double theZ,
double theSize): gp_Pnt(theX, theY, theZ)
{
size=theSize;
}
DriverGMF_Write::DriverGMF_Write(): DriverGMF_Write::DriverGMF_Write():
Driver_SMESHDS_Mesh(), _exportRequiredGroups( true ) Driver_SMESHDS_Mesh(), _exportRequiredGroups( true )
{ {
@ -365,7 +344,7 @@ Driver_Mesh::Status DriverGMF_Write::Perform()
return DRS_OK; return DRS_OK;
} }
Driver_Mesh::Status DriverGMF_Write::PerformSizeMap( const std::vector<Control_Pnt>& points ) Driver_Mesh::Status DriverGMF_Write::PerformSizeMap( const std::vector<ControlPnt>& points )
{ {
// const int dim = 3, version = sizeof(long) == 4 ? 2 : 3; // const int dim = 3, version = sizeof(long) == 4 ? 2 : 3;
const int dim = 3, version = 2; // Version 3 not supported by mg-hexa const int dim = 3, version = 2; // Version 3 not supported by mg-hexa
@ -383,7 +362,7 @@ Driver_Mesh::Status DriverGMF_Write::PerformSizeMap( const std::vector<Control_P
GmfSetKwd(solFileID, GmfSolAtVertices, pointsNumber, 1, TypTab); GmfSetKwd(solFileID, GmfSolAtVertices, pointsNumber, 1, TypTab);
// Read the control points information from the vector and write it into the files // Read the control points information from the vector and write it into the files
std::vector<Control_Pnt>::const_iterator points_it; std::vector<ControlPnt>::const_iterator points_it;
for (points_it = points.begin(); points_it != points.end(); points_it++ ) for (points_it = points.begin(); points_it != points.end(); points_it++ )
{ {
GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 ); GmfSetLin( verticesFileID, GmfVertices, points_it->X(), points_it->Y(), points_it->Z(), 0 );

View File

@ -32,26 +32,7 @@
#include "Driver_SMESHDS_Mesh.h" #include "Driver_SMESHDS_Mesh.h"
#include "SMDSAbs_ElementType.hxx" #include "SMDSAbs_ElementType.hxx"
#include "SMDS_ElemIterator.hxx" #include "SMDS_ElemIterator.hxx"
#include "SMESH_ControlPnt.hxx"
#include <gp_Pnt.hxx>
/*!
* \brief Class for storing control points for writing GMF size maps
*/
class MESHDriverGMF_EXPORT Control_Pnt : public gp_Pnt
{
public:
Control_Pnt();
Control_Pnt(const gp_Pnt& aPnt, double theSize);
Control_Pnt(double x, double y, double z);
Control_Pnt(double x, double y, double z, double size);
double Size() const { return size; };
void SetSize( double theSize ) { size = theSize; };
private:
double size;
};
/*! /*!
* \brief Driver Writing a mesh into a GMF file. * \brief Driver Writing a mesh into a GMF file.
@ -71,7 +52,7 @@ public:
virtual Status Perform(); virtual Status Perform();
// Size Maps // Size Maps
Status PerformSizeMap( const std::vector<Control_Pnt>& points ); Status PerformSizeMap( const std::vector<SMESHUtils::ControlPnt>& points );
void SetSizeMapPrefix( std::string prefix ) void SetSizeMapPrefix( std::string prefix )
{ {
myVerticesFile = prefix + ".mesh"; myVerticesFile = prefix + ".mesh";

View File

@ -53,7 +53,7 @@ public:
template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]] template< class VECT > // interlacedIDs[i] = smdsIDs[ indices[ i ]]
static void applyInterlace( const std::vector<int>& interlace, VECT & data) static void applyInterlace( const std::vector<int>& interlace, VECT & data)
{ {
if ( interlace.empty() ) return; if ( interlace.size() < data.size() ) return;
VECT tmpData( data.size() ); VECT tmpData( data.size() );
for ( size_t i = 0; i < data.size(); ++i ) for ( size_t i = 0; i < data.size(); ++i )
tmpData[i] = data[ interlace[i] ]; tmpData[i] = data[ interlace[i] ];
@ -62,7 +62,7 @@ public:
template< class VECT > // interlacedIDs[ indices[ i ]] = smdsIDs[i] template< class VECT > // interlacedIDs[ indices[ i ]] = smdsIDs[i]
static void applyInterlaceRev( const std::vector<int>& interlace, VECT & data) static void applyInterlaceRev( const std::vector<int>& interlace, VECT & data)
{ {
if ( interlace.empty() ) return; if ( interlace.size() < data.size() ) return;
VECT tmpData( data.size() ); VECT tmpData( data.size() );
for ( size_t i = 0; i < data.size(); ++i ) for ( size_t i = 0; i < data.size(); ++i )
tmpData[ interlace[i] ] = data[i]; tmpData[ interlace[i] ] = data[i];

View File

@ -919,7 +919,7 @@ void SMESHGUI_AddMeshElementDlg::displaySimulation()
if (ReverseOrDulicate && ReverseOrDulicate->isChecked()) if (ReverseOrDulicate && ReverseOrDulicate->isChecked())
{ {
const std::vector<int>& i = SMDS_MeshCell::reverseSmdsOrder( myGeomType ); const std::vector<int>& i = SMDS_MeshCell::reverseSmdsOrder( myGeomType );
if ( i.empty() ) // polygon if ( i.size() != anIds.size() ) // polygon
std::reverse( anIds.begin(), anIds.end() ); std::reverse( anIds.begin(), anIds.end() );
else else
SMDS_MeshCell::applyInterlace( i, anIds ); SMDS_MeshCell::applyInterlace( i, anIds );

View File

@ -65,6 +65,7 @@ SET(SMESHUtils_HEADERS
SMESH_TryCatch.hxx SMESH_TryCatch.hxx
SMESH_MeshAlgos.hxx SMESH_MeshAlgos.hxx
SMESH_MAT2d.hxx SMESH_MAT2d.hxx
SMESH_ControlPnt.hxx
) )
# --- sources --- # --- sources ---
@ -80,6 +81,7 @@ SET(SMESHUtils_SOURCES
SMESH_MeshAlgos.cxx SMESH_MeshAlgos.cxx
SMESH_MAT2d.cxx SMESH_MAT2d.cxx
SMESH_FreeBorders.cxx SMESH_FreeBorders.cxx
SMESH_ControlPnt.cxx
) )
# --- rules --- # --- rules ---

View File

@ -0,0 +1,414 @@
// Copyright (C) 2007-2016 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// Author : Lioka RAZAFINDRAZAKA (CEA)
#include "SMESH_ControlPnt.hxx"
#include <BRepBndLib.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <Bnd_Box.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Curve.hxx>
#include <IntCurvesFace_Intersector.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <Poly_Triangle.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TopExp_Explorer.hxx>
#include <TopLoc_Location.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Solid.hxx>
#include <gp_Ax3.hxx>
#include <gp_Dir.hxx>
#include <gp_Lin.hxx>
#include <gp_Trsf.hxx>
#include <gp_Vec.hxx>
#include <set>
namespace SMESHUtils
{
// Some functions for surface sampling
void subdivideTriangle( const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& p3,
const double& theSize,
std::vector<ControlPnt>& thePoints );
std::vector<gp_Pnt> computePointsForSplitting( const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& p3 );
gp_Pnt tangencyPoint(const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& Center);
}
//================================================================================
/*!
* \brief Fills a vector of points from which a size map input file can be written
*/
//================================================================================
void SMESHUtils::createControlPoints( const TopoDS_Shape& theShape,
const double& theSize,
std::vector<ControlPnt>& thePoints )
{
if ( theShape.ShapeType() == TopAbs_VERTEX )
{
gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex(theShape) );
ControlPnt aControlPnt( aPnt, theSize );
thePoints.push_back( aControlPnt );
}
if ( theShape.ShapeType() == TopAbs_EDGE )
{
createPointsSampleFromEdge( TopoDS::Edge( theShape ), theSize, thePoints );
}
else if ( theShape.ShapeType() == TopAbs_WIRE )
{
TopExp_Explorer Ex;
for (Ex.Init(theShape,TopAbs_EDGE); Ex.More(); Ex.Next())
{
createPointsSampleFromEdge( TopoDS::Edge( Ex.Current() ), theSize, thePoints );
}
}
else if ( theShape.ShapeType() == TopAbs_FACE )
{
createPointsSampleFromFace( TopoDS::Face( theShape ), theSize, thePoints );
}
else if ( theShape.ShapeType() == TopAbs_SOLID )
{
createPointsSampleFromSolid( TopoDS::Solid( theShape ), theSize, thePoints );
}
else if ( theShape.ShapeType() == TopAbs_COMPOUND )
{
TopoDS_Iterator it( theShape );
for(; it.More(); it.Next())
{
createControlPoints( it.Value(), theSize, thePoints );
}
}
}
//================================================================================
/*!
* \brief Fills a vector of points with point samples approximately
* \brief spaced with a given size
*/
//================================================================================
void SMESHUtils::createPointsSampleFromEdge( const TopoDS_Edge& theEdge,
const double& theSize,
std::vector<ControlPnt>& thePoints )
{
double step = theSize;
double first, last;
Handle( Geom_Curve ) aCurve = BRep_Tool::Curve( theEdge, first, last );
GeomAdaptor_Curve C ( aCurve );
GCPnts_UniformAbscissa DiscretisationAlgo(C, step , first, last, Precision::Confusion());
int nbPoints = DiscretisationAlgo.NbPoints();
ControlPnt aPnt;
aPnt.SetSize(theSize);
for ( int i = 1; i <= nbPoints; i++ )
{
double param = DiscretisationAlgo.Parameter( i );
aCurve->D0( param, aPnt );
thePoints.push_back( aPnt );
}
}
//================================================================================
/*!
* \brief Fills a vector of points with point samples approximately
* \brief spaced with a given size
*/
//================================================================================
void SMESHUtils::createPointsSampleFromFace( const TopoDS_Face& theFace,
const double& theSize,
std::vector<ControlPnt>& thePoints )
{
BRepMesh_IncrementalMesh M(theFace, 0.01, Standard_True);
TopLoc_Location aLocation;
// Triangulate the face
Handle(Poly_Triangulation) aTri = BRep_Tool::Triangulation (theFace, aLocation);
// Get the transformation associated to the face location
gp_Trsf aTrsf = aLocation.Transformation();
// Get triangles
int nbTriangles = aTri->NbTriangles();
Poly_Array1OfTriangle triangles(1,nbTriangles);
triangles=aTri->Triangles();
// GetNodes
int nbNodes = aTri->NbNodes();
TColgp_Array1OfPnt nodes(1,nbNodes);
nodes = aTri->Nodes();
// Iterate on triangles and subdivide them
for(int i=1; i<=nbTriangles; i++)
{
Poly_Triangle aTriangle = triangles.Value(i);
gp_Pnt p1 = nodes.Value(aTriangle.Value(1));
gp_Pnt p2 = nodes.Value(aTriangle.Value(2));
gp_Pnt p3 = nodes.Value(aTriangle.Value(3));
p1.Transform(aTrsf);
p2.Transform(aTrsf);
p3.Transform(aTrsf);
subdivideTriangle(p1, p2, p3, theSize, thePoints);
}
}
//================================================================================
/*!
* \brief Fills a vector of points with point samples approximately
* \brief spaced with a given size
*/
//================================================================================
void SMESHUtils::createPointsSampleFromSolid( const TopoDS_Solid& theSolid,
const double& theSize,
std::vector<ControlPnt>& thePoints )
{
// Compute the bounding box
double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
Bnd_Box B;
BRepBndLib::Add(theSolid, B);
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
// Create the points
double step = theSize;
for ( double x=Xmin; x-Xmax<Precision::Confusion(); x=x+step )
{
for ( double y=Ymin; y-Ymax<Precision::Confusion(); y=y+step )
{
// Step1 : generate the Zmin -> Zmax line
gp_Pnt startPnt(x, y, Zmin);
gp_Pnt endPnt(x, y, Zmax);
gp_Vec aVec(startPnt, endPnt);
gp_Lin aLine(startPnt, aVec);
double endParam = Zmax - Zmin;
// Step2 : for each face of theSolid:
std::set<double> intersections;
std::set<double>::iterator it = intersections.begin();
TopExp_Explorer Ex;
for (Ex.Init(theSolid,TopAbs_FACE); Ex.More(); Ex.Next())
{
// check if there is an intersection
IntCurvesFace_Intersector anIntersector(TopoDS::Face(Ex.Current()), Precision::Confusion());
anIntersector.Perform(aLine, 0, endParam);
// get the intersection's parameter and store it
int nbPoints = anIntersector.NbPnt();
for(int i = 0 ; i < nbPoints ; i++ )
{
it = intersections.insert( it, anIntersector.WParameter(i+1) );
}
}
// Step3 : go through the line chunk by chunk
if ( intersections.begin() != intersections.end() )
{
std::set<double>::iterator intersectionsIterator=intersections.begin();
double first = *intersectionsIterator;
intersectionsIterator++;
bool innerPoints = true;
for ( ; intersectionsIterator!=intersections.end() ; intersectionsIterator++ )
{
double second = *intersectionsIterator;
if ( innerPoints )
{
// If the last chunk was outside of the shape or this is the first chunk
// add the points in the range [first, second] to the points vector
double localStep = (second -first) / ceil( (second - first) / step );
for ( double z = Zmin + first; z < Zmin + second; z = z + localStep )
{
thePoints.push_back(ControlPnt( x, y, z, theSize ));
}
thePoints.push_back(ControlPnt( x, y, Zmin + second, theSize ));
}
first = second;
innerPoints = !innerPoints;
}
}
}
}
}
//================================================================================
/*!
* \brief Subdivides a triangle until it reaches a certain size (recursive function)
*/
//================================================================================
void SMESHUtils::subdivideTriangle( const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& p3,
const double& theSize,
std::vector<ControlPnt>& thePoints)
{
// Size threshold to stop subdividing
// This value ensures that two control points are distant no more than 2*theSize
// as shown below
//
// The greater distance D of the mass center M to each Edge is 1/3 * Median
// and Median < sqrt(3/4) * a where a is the greater side (by using Apollonius' thorem).
// So D < 1/3 * sqrt(3/4) * a and if a < sqrt(3) * S then D < S/2
// and the distance between two mass centers of two neighbouring triangles
// sharing an edge is < 2 * 1/2 * S = S
// If the traingles share a Vertex and no Edge the distance of the mass centers
// to the Vertices is 2*D < S so the mass centers are distant of less than 2*S
double threshold = sqrt( 3. ) * theSize;
if ( (p1.Distance(p2) > threshold ||
p2.Distance(p3) > threshold ||
p3.Distance(p1) > threshold))
{
std::vector<gp_Pnt> midPoints = computePointsForSplitting(p1, p2, p3);
subdivideTriangle( midPoints[0], midPoints[1], midPoints[2], theSize, thePoints );
subdivideTriangle( midPoints[0], p2, midPoints[1], theSize, thePoints );
subdivideTriangle( midPoints[2], midPoints[1], p3, theSize, thePoints );
subdivideTriangle( p1, midPoints[0], midPoints[2], theSize, thePoints );
}
else
{
double x = (p1.X() + p2.X() + p3.X()) / 3 ;
double y = (p1.Y() + p2.Y() + p3.Y()) / 3 ;
double z = (p1.Z() + p2.Z() + p3.Z()) / 3 ;
ControlPnt massCenter( x ,y ,z, theSize );
thePoints.push_back( massCenter );
}
}
//================================================================================
/*!
* \brief Returns the appropriate points for splitting a triangle
* \brief the tangency points of the incircle are used in order to have mostly
* \brief well-shaped sub-triangles
*/
//================================================================================
std::vector<gp_Pnt> SMESHUtils::computePointsForSplitting( const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& p3 )
{
std::vector<gp_Pnt> midPoints;
//Change coordinates
gp_Trsf Trsf_1; // Identity transformation
gp_Ax3 reference_system(gp::Origin(), gp::DZ(), gp::DX()); // OXY
gp_Vec Vx(p1, p3);
gp_Vec Vaux(p1, p2);
gp_Dir Dx(Vx);
gp_Dir Daux(Vaux);
gp_Dir Dz = Dx.Crossed(Daux);
gp_Ax3 current_system(p1, Dz, Dx);
Trsf_1.SetTransformation( reference_system, current_system );
gp_Pnt A = p1.Transformed(Trsf_1);
gp_Pnt B = p2.Transformed(Trsf_1);
gp_Pnt C = p3.Transformed(Trsf_1);
double a = B.Distance(C) ;
double b = A.Distance(C) ;
double c = B.Distance(A) ;
// Incenter coordinates
// see http://mathworld.wolfram.com/Incenter.html
double Xi = ( b*B.X() + c*C.X() ) / ( a + b + c );
double Yi = ( b*B.Y() ) / ( a + b + c );
gp_Pnt Center(Xi, Yi, 0);
// Calculate the tangency points of the incircle
gp_Pnt T1 = tangencyPoint( A, B, Center);
gp_Pnt T2 = tangencyPoint( B, C, Center);
gp_Pnt T3 = tangencyPoint( C, A, Center);
gp_Pnt p1_2 = T1.Transformed(Trsf_1.Inverted());
gp_Pnt p2_3 = T2.Transformed(Trsf_1.Inverted());
gp_Pnt p3_1 = T3.Transformed(Trsf_1.Inverted());
midPoints.push_back(p1_2);
midPoints.push_back(p2_3);
midPoints.push_back(p3_1);
return midPoints;
}
//================================================================================
/*!
* \brief Computes the tangency points of the circle of center Center with
* \brief the straight line (p1 p2)
*/
//================================================================================
gp_Pnt SMESHUtils::tangencyPoint(const gp_Pnt& p1,
const gp_Pnt& p2,
const gp_Pnt& Center)
{
double Xt = 0;
double Yt = 0;
// The tangency point is the intersection of the straight line (p1 p2)
// and the straight line (Center T) which is orthogonal to (p1 p2)
if ( fabs(p1.X() - p2.X()) <= Precision::Confusion() )
{
Xt=p1.X(); // T is on (p1 p2)
Yt=Center.Y(); // (Center T) is orthogonal to (p1 p2)
}
else if ( fabs(p1.Y() - p2.Y()) <= Precision::Confusion() )
{
Yt=p1.Y(); // T is on (p1 p2)
Xt=Center.X(); // (Center T) is orthogonal to (p1 p2)
}
else
{
// First straight line coefficients (equation y=a*x+b)
double a = (p2.Y() - p1.Y()) / (p2.X() - p1.X()) ;
double b = p1.Y() - a*p1.X(); // p1 is on this straight line
// Second straight line coefficients (equation y=c*x+d)
double c = -1 / a; // The 2 lines are orthogonal
double d = Center.Y() - c*Center.X(); // Center is on this straight line
Xt = (d - b) / (a - c);
Yt = a*Xt + b;
}
return gp_Pnt( Xt, Yt, 0 );
}

View File

@ -0,0 +1,76 @@
// Copyright (C) 2007-2016 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
// Author : Lioka RAZAFINDRAZAKA (CEA)
#ifndef SMESH_CONTROLPNT_H
#define SMESH_CONTROLPNT_H
#include "SMESH_Utils.hxx"
#include <gp_Pnt.hxx>
class TopoDS_Shape;
class TopoDS_Edge ;
class TopoDS_Face ;
class TopoDS_Solid;
#include <vector>
namespace SMESHUtils
{
/*!
* \brief Control point: coordinates and element size at these coordinates
*/
struct SMESHUtils_EXPORT ControlPnt : public gp_Pnt
{
ControlPnt()
: gp_Pnt(), size(0) {}
ControlPnt( const gp_Pnt& aPnt, double theSize)
: gp_Pnt( aPnt ), size( theSize ) {}
ControlPnt(double theX,double theY,double theZ)
: gp_Pnt(theX, theY, theZ), size(0) {}
ControlPnt(double theX,double theY,double theZ, double theSize)
: gp_Pnt(theX, theY, theZ), size( theSize ) {}
double Size() const { return size; };
void SetSize( double theSize ) { size = theSize; };
double size;
};
// Functions to get sample point from shapes
void createControlPoints( const TopoDS_Shape& theShape,
const double& theSize,
std::vector< ControlPnt >& thePoints );
void createPointsSampleFromEdge( const TopoDS_Edge& theEdge,
const double& theSize,
std::vector<ControlPnt>& thePoints );
void createPointsSampleFromFace( const TopoDS_Face& theFace,
const double& theSize,
std::vector<ControlPnt>& thePoints );
void createPointsSampleFromSolid( const TopoDS_Solid& theSolid,
const double& theSize,
std::vector<ControlPnt>& thePoints );
}
#endif

View File

@ -53,10 +53,10 @@ namespace SMESH
size_t TPythonDump::myCounter = 0; size_t TPythonDump::myCounter = 0;
const char theNotPublishedObjectName[] = "__NOT__Published__Object__"; const char theNotPublishedObjectName[] = "__NOT__Published__Object__";
TVar::TVar(CORBA::Double value):myVals(1) { myVals[0] = SMESH_Comment(value); } TVar::TVar(CORBA::Double value):myVals(1), myIsList(false) { myVals[0] = SMESH_Comment(value); }
TVar::TVar(CORBA::Long value):myVals(1) { myVals[0] = SMESH_Comment(value); } TVar::TVar(CORBA::Long value):myVals(1), myIsList(false) { myVals[0] = SMESH_Comment(value); }
TVar::TVar(CORBA::Short value):myVals(1) { myVals[0] = SMESH_Comment(value); } TVar::TVar(CORBA::Short value):myVals(1), myIsList(false) { myVals[0] = SMESH_Comment(value); }
TVar::TVar(const SMESH::double_array& value):myVals(value.length()) TVar::TVar(const SMESH::double_array& value):myVals(value.length()), myIsList(true)
{ {
for ( size_t i = 0; i < value.length(); i++) for ( size_t i = 0; i < value.length(); i++)
myVals[i] = SMESH_Comment(value[i]); myVals[i] = SMESH_Comment(value[i]);
@ -93,7 +93,7 @@ namespace SMESH
operator<<(const TVar& theVarValue) operator<<(const TVar& theVarValue)
{ {
const std::vector< int >& varIDs = SMESH_Gen_i::GetSMESHGen()->GetLastParamIndices(); const std::vector< int >& varIDs = SMESH_Gen_i::GetSMESHGen()->GetLastParamIndices();
if ( theVarValue.myVals.size() != 1 ) if ( theVarValue.myIsList )
{ {
myStream << "[ "; myStream << "[ ";
for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i ) for ( size_t i = 1; i <= theVarValue.myVals.size(); ++i )

View File

@ -99,6 +99,7 @@ namespace SMESH
struct SMESH_I_EXPORT TVar struct SMESH_I_EXPORT TVar
{ {
std::vector< std::string > myVals; std::vector< std::string > myVals;
bool myIsList;
TVar(CORBA::Double value); TVar(CORBA::Double value);
TVar(CORBA::Long value); TVar(CORBA::Long value);
TVar(CORBA::Short value); TVar(CORBA::Short value);

View File

@ -4505,7 +4505,7 @@ class Mesh:
## Finds groups of ajacent nodes within Tolerance. ## Finds groups of ajacent nodes within Tolerance.
# @param Tolerance the value of tolerance # @param Tolerance the value of tolerance
# @param SubMeshOrGroup SubMesh or Group # @param SubMeshOrGroup SubMesh, Group or Filter
# @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search # @param exceptNodes list of either SubMeshes, Groups or node IDs to exclude from search
# @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts # @param SeparateCornerAndMediumNodes if @c True, in quadratic mesh puts
# corner and medium nodes in separate groups thus preventing # corner and medium nodes in separate groups thus preventing

View File

@ -82,7 +82,6 @@ using namespace std;
StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen * gen): StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen * gen):
SMESH_2D_Algo(hypId, studyId, gen) SMESH_2D_Algo(hypId, studyId, gen)
{ {
MESSAGE("StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D");
_name = "MEFISTO_2D"; _name = "MEFISTO_2D";
_shapeType = (1 << TopAbs_FACE); _shapeType = (1 << TopAbs_FACE);
_compatibleHypothesis.push_back("MaxElementArea"); _compatibleHypothesis.push_back("MaxElementArea");
@ -104,7 +103,6 @@ StdMeshers_MEFISTO_2D::StdMeshers_MEFISTO_2D(int hypId, int studyId, SMESH_Gen *
StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D() StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D()
{ {
MESSAGE("StdMeshers_MEFISTO_2D::~StdMeshers_MEFISTO_2D");
} }
//============================================================================= //=============================================================================
@ -189,8 +187,6 @@ bool StdMeshers_MEFISTO_2D::CheckHypothesis
bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{ {
MESSAGE("StdMeshers_MEFISTO_2D::Compute");
TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD)); TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
// helper builds quadratic mesh if necessary // helper builds quadratic mesh if necessary
@ -284,8 +280,6 @@ bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aSh
if (ierr == 0) if (ierr == 0)
{ {
MESSAGE("... End Triangulation Generated Triangle Number " << nbt);
MESSAGE(" Node Number " << nbst);
StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley); StoreResult(nbst, uvst, nbt, nust, mefistoToDS, scalex, scaley);
isOk = true; isOk = true;
} }
@ -313,8 +307,6 @@ bool StdMeshers_MEFISTO_2D::Evaluate(SMESH_Mesh & aMesh,
const TopoDS_Shape & aShape, const TopoDS_Shape & aShape,
MapShapeNbElems& aResMap) MapShapeNbElems& aResMap)
{ {
MESSAGE("StdMeshers_MEFISTO_2D::Evaluate");
TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD)); TopoDS_Face F = TopoDS::Face(aShape.Oriented(TopAbs_FORWARD));
double aLen = 0.0; double aLen = 0.0;

View File

@ -306,6 +306,24 @@ namespace
} }
deviation2sideInd.insert( make_pair( devia, iS )); deviation2sideInd.insert( make_pair( devia, iS ));
} }
double maxDevi = deviation2sideInd.rbegin()->first;
if ( maxDevi < 1e-7 && sides.size() == 3 )
{
// a triangle FACE; use a side with the most outstanding length as an elliptic one
deviation2sideInd.clear();
multimap< double, int > len2sideInd;
for ( size_t iS = 0; iS < sides.size(); ++iS )
len2sideInd.insert( make_pair( sides[iS]->Length(), iS ));
multimap< double, int >::iterator l2i = len2sideInd.begin();
double len0 = l2i->first;
double len1 = (++l2i)->first;
double len2 = (++l2i)->first;
if ( len1 - len0 > len2 - len1 )
deviation2sideInd.insert( make_pair( 0., len2sideInd.begin()->second ));
else
deviation2sideInd.insert( make_pair( 0., len2sideInd.rbegin()->second ));
}
int iCirc = deviation2sideInd.rbegin()->second; int iCirc = deviation2sideInd.rbegin()->second;
aCircSide = sides[ iCirc ]; aCircSide = sides[ iCirc ];

View File

@ -991,7 +991,9 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
case FIXED_POINTS_1D: case FIXED_POINTS_1D:
{ {
const std::vector<double>& aPnts = _fpHyp->GetPoints(); const std::vector<double>& aPnts = _fpHyp->GetPoints();
const std::vector<int>& nbsegs = _fpHyp->GetNbSegments(); std::vector<int> nbsegs = _fpHyp->GetNbSegments();
if ( theReverse )
std::reverse( nbsegs.begin(), nbsegs.end() );
// sort normalized params, taking into account theReverse // sort normalized params, taking into account theReverse
TColStd_SequenceOfReal Params; TColStd_SequenceOfReal Params;
@ -1146,7 +1148,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
{ {
list< double > params; list< double > params;
bool reversed = false; bool reversed = false;
if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE ) { if ( theMesh.GetShapeToMesh().ShapeType() >= TopAbs_WIRE && _revEdgesIDs.empty() ) {
// if the shape to mesh is WIRE or EDGE // if the shape to mesh is WIRE or EDGE
reversed = ( EE.Orientation() == TopAbs_REVERSED ); reversed = ( EE.Orientation() == TopAbs_REVERSED );
} }