IPAL054122: Bad quality prismatic mesh

Fix applying the boundary error in StdMeshers_Sweeper by using
StdMeshers_Delaunay
This commit is contained in:
eap 2017-04-25 13:41:21 +03:00
parent e5b4cc5b6e
commit 3dcb8f1e04
11 changed files with 253 additions and 587 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -6,6 +6,8 @@ Extrusion 3D algorithm can be used for meshing prisms, i.e. 3D shapes
defined by two opposing faces having the same number of vertices and
edges. These two faces should be connected by quadrangle "side" faces.
\image html prism_mesh.png "Clipping view of a mesh of a prism with non-planar base and top faces"
The prism is allowed to have sides composed of several faces. (A prism
side is a row of faces (or one face) connecting the corresponding edges of
the top and base faces). However, a prism

View File

@ -602,7 +602,6 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
Extrema_GenExtPS projector;
GeomAdaptor_Surface aSurface( BRep_Tool::Surface( face ));
if ( theProject || needProject )
projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
int iPoint = 0;
@ -690,8 +689,28 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
myPoints.resize( nbNodes );
// care of INTERNAL VERTEXes
TopExp_Explorer vExp( face, TopAbs_VERTEX, TopAbs_EDGE );
for ( ; vExp.More(); vExp.Next() )
{
const SMDS_MeshNode* node =
SMESH_Algo::VertexNode( TopoDS::Vertex( vExp.Current()), aMeshDS );
if ( !node || node->NbInverseElements( SMDSAbs_Face ) == 0 )
continue;
myPoints.resize( ++nbNodes );
list< TPoint* > & fPoints = getShapePoints( face );
nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* p = &myPoints[ iPoint++ ];
fPoints.push_back( p );
gp_XY uv = helper.GetNodeUV( face, node );
p->myInitUV.SetCoord( uv.X(), uv.Y() );
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
}
// Load U of points on edges
Bnd_Box2d edgesUVBox;
list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
int iE = 0;
vector< TopoDS_Edge > eVec;
@ -762,6 +781,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
else
keyPoint->myInitUV = C2d->Value( isForward ? f : l ).XY();
keyPoint->myInitXYZ.SetCoord (keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0);
edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
}
}
if ( !vPoint->empty() )
@ -841,6 +861,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
p->myInitUV = C2d->Value( u ).XY();
}
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
edgesUVBox.Add( gp_Pnt2d( p->myInitUV ));
unIt++; unRIt++;
iPoint++;
}
@ -866,6 +887,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
else
keyPoint->myInitUV = C2d->Value( isForward ? l : f ).XY();
keyPoint->myInitXYZ.SetCoord( keyPoint->myInitUV.X(), keyPoint->myInitUV.Y(), 0 );
edgesUVBox.Add( gp_Pnt2d( keyPoint->myInitUV ));
}
}
if ( !vPoint->empty() )
@ -906,7 +928,7 @@ bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* p = &myPoints[ iPoint++ ];
fPoints.push_back( p );
if ( theProject )
if ( theProject || edgesUVBox.IsOut( p->myInitUV ) )
p->myInitUV = project( node, projector );
else {
const SMDS_FacePosition* pos =

View File

@ -24,6 +24,9 @@
// Author : Edward AGAPOV (eap)
#include "SMESH_Delaunay.hxx"
#include "SMESH_Comment.hxx"
#include "SMESH_File.hxx"
#include "SMESH_MeshAlgos.hxx"
#include <BRepAdaptor_Surface.hxx>
@ -233,6 +236,7 @@ const BRepMesh_Triangle* SMESH_Delaunay::FindTriangle( const gp_XY&
if ( 0. <= uSeg && uSeg <= 1. )
{
tria = & _triaDS->GetElement( triIDs.Index( 1 + ( triIDs.Index(1) == triaID )));
if ( tria->Movability() != BRepMesh_Deleted )
break;
}
}
@ -250,11 +254,39 @@ const BRepMesh_Triangle* SMESH_Delaunay::FindTriangle( const gp_XY&
const BRepMesh_Triangle* SMESH_Delaunay::GetTriangleNear( int iBndNode )
{
int nodeIDs[3];
int nbNbNodes = _bndNodes.size();
const BRepMesh::ListOfInteger & linkIds = _triaDS->LinksConnectedTo( iBndNode + 1 );
const BRepMesh_PairOfIndex & triaIds = _triaDS->ElementsConnectedTo( linkIds.First() );
BRepMesh::ListOfInteger::const_iterator iLink = linkIds.cbegin();
for ( ; iLink != linkIds.cend(); ++iLink )
{
const BRepMesh_PairOfIndex & triaIds = _triaDS->ElementsConnectedTo( *iLink );
{
const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(1) );
if ( tria.Movability() != BRepMesh_Deleted )
{
_triaDS->ElementNodes( tria, nodeIDs );
if ( nodeIDs[0]-1 < nbNbNodes &&
nodeIDs[1]-1 < nbNbNodes &&
nodeIDs[2]-1 < nbNbNodes )
return &tria;
}
}
if ( triaIds.Extent() > 1 )
{
const BRepMesh_Triangle& tria = _triaDS->GetElement( triaIds.Index(2) );
if ( tria.Movability() != BRepMesh_Deleted )
{
_triaDS->ElementNodes( tria, nodeIDs );
if ( nodeIDs[0]-1 < nbNbNodes &&
nodeIDs[1]-1 < nbNbNodes &&
nodeIDs[2]-1 < nbNbNodes )
return &tria;
}
}
}
return 0;
}
//================================================================================
/*!
@ -294,3 +326,43 @@ void SMESH_Delaunay::addCloseNodes( const SMDS_MeshNode* node,
}
}
}
//================================================================================
/*!
* \brief Write a python script that creates an equal mesh in Mesh module
*/
//================================================================================
void SMESH_Delaunay::ToPython() const
{
SMESH_Comment text;
text << "import salome, SMESH\n";
text << "salome.salome_init()\n";
text << "from salome.smesh import smeshBuilder\n";
text << "smesh = smeshBuilder.New(salome.myStudy)\n";
text << "mesh=smesh.Mesh()\n";
const char* endl = "\n";
for ( int i = 0; i < _triaDS->NbNodes(); ++i )
{
const BRepMesh_Vertex& v = _triaDS->GetNode( i+1 );
text << "mesh.AddNode( " << v.Coord().X() << ", " << v.Coord().Y() << ", 0 )" << endl;
}
int nodeIDs[3];
for ( int i = 0; i < _triaDS->NbElements(); ++i )
{
const BRepMesh_Triangle& t = _triaDS->GetElement( i+1 );
if ( t.Movability() == BRepMesh_Deleted )
continue;
_triaDS->ElementNodes( t, nodeIDs );
text << "mesh.AddFace([ " << nodeIDs[0] << ", " << nodeIDs[1] << ", " << nodeIDs[2] << " ])" << endl;
}
const char* fileName = "/tmp/Delaunay.py";
SMESH_File file( fileName, false );
file.remove();
file.openForWriting();
file.write( text.c_str(), text.size() );
cout << "execfile( '" << fileName << "')" << endl;
}

View File

@ -83,6 +83,9 @@ class SMESHUtils_EXPORT SMESH_Delaunay
// delauney_UV = real_UV * scale
const gp_XY& GetScale() const { return _scale; }
void ToPython() const;
Handle(BRepMesh_DataStructureOfDelaun) GetDS() { return _triaDS; }
protected:

View File

@ -22,8 +22,6 @@
# scripts / static
SET(_bin_SCRIPTS
smesh.py
batchmode_smesh.py
batchmode_mefisto.py
ex00_all.py
ex01_cube2build.py
ex02_cube2primitive.py

View File

@ -1,127 +0,0 @@
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
#
# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, 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
#
import os
import re
import batchmode_salome
import batchmode_geompy
import batchmode_smesh
from salome.StdMeshers import StdMeshersBuilder
smesh = batchmode_smesh.smesh
smesh.SetCurrentStudy(batchmode_salome.myStudy)
def CreateMesh (theFileName, area, len = None, nbseg = None):
if not(os.path.isfile(theFileName)) or re.search("\.brep$", theFileName) is None :
print "Incorrect file name !"
return
if (len is None) and (nbseg is None):
print "Define length or number of segments !"
return
if (len is not None) and (nbseg is not None):
print "Only one Hypothesis (from length and number of segments) can be defined !"
return
# ---- Import shape from BREP file and add it to the study
shape_mesh = batchmode_geompy.Import(theFileName, "BREP")
Id_shape = batchmode_geompy.addToStudy(shape_mesh, "shape_mesh")
# ---- SMESH
print "-------------------------- create mesh"
mesh = smesh.Mesh(shape_mesh)
print "-------------------------- create Hypothesis"
if (len is not None):
print "-------------------------- LocalLength"
algoReg = mesh.Segment()
hypLength1 = algoReg.LocalLength(len)
print "Hypothesis type : ", hypLength1.GetName()
print "Hypothesis ID : ", hypLength1.GetId()
print "Hypothesis Value: ", hypLength1.GetLength()
if (nbseg is not None):
print "-------------------------- NumberOfSegments"
algoReg = mesh.Segment()
hypNbSeg1 = algoReg.NumberOfSegments(nbseg)
print "Hypothesis type : ", hypNbSeg1.GetName()
print "Hypothesis ID : ", hypNbSeg1.GetId()
print "Hypothesis Value: ", hypNbSeg1.GetNumberOfSegments()
if (area == "LengthFromEdges"):
print "-------------------------- LengthFromEdges"
algoMef = mesh.Triangle()
hypLengthFromEdges = algoMef.LengthFromEdges(1)
print "Hypothesis type : ", hypLengthFromEdges.GetName()
print "Hypothesis ID : ", hypLengthFromEdges.GetId()
print "LengthFromEdges Mode: ", hypLengthFromEdges.GetMode()
else:
print "-------------------------- MaxElementArea"
algoMef = mesh.Triangle()
hypArea1 = algoMef.MaxElementArea(area)
print "Hypothesis type : ", hypArea1.GetName()
print "Hypothesis ID : ", hypArea1.GetId()
print "Hypothesis Value: ", hypArea1.GetMaxElementArea()
print "-------------------------- Regular_1D"
listHyp = algoReg.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
print "Algo name: ", algoReg.GetName()
print "Algo ID : ", algoReg.GetId()
print "-------------------------- MEFISTO_2D"
listHyp = algoMef.GetCompatibleHypothesis()
for hyp in listHyp:
print hyp
print "Algo name: ", algoMef.GetName()
print "Algo ID : ", algoMef.GetId()
# ---- add hypothesis to shape
print "-------------------------- compute mesh"
ret = mesh.Compute()
print "Compute Mesh .... ",
print ret
log = mesh.GetLog(0); # no erase trace
#for linelog in log:
# print linelog
print "------------ INFORMATION ABOUT MESH ------------"
print "Number of nodes : ", mesh.NbNodes()
print "Number of edges : ", mesh.NbEdges()
print "Number of faces : ", mesh.NbFaces()
print "Number of triangles: ", mesh.NbTriangles()
return mesh

View File

@ -1,324 +0,0 @@
# -*- coding: iso-8859-1 -*-
# Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
#
# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, 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
#
# File : batchmode_smesh.py
# Author : Oksana TCHEBANOVA
# Module : SMESH
# $Header$
#
from batchmode_salome import *
from batchmode_geompy import ShapeType
import SMESH
#--------------------------------------------------------------------------
modulecatalog = naming_service.Resolve("/Kernel/ModulCatalog")
smesh = lcc.FindOrLoadComponent("FactoryServer", "SMESH")
smesh.SetCurrentStudy(myStudy)
myStudyBuilder = myStudy.NewBuilder()
if myStudyBuilder is None:
raise RuntimeError, " Null myStudyBuilder"
father = myStudy.FindComponent("SMESH")
if father is None:
father = myStudyBuilder.NewComponent("SMESH")
FName = myStudyBuilder.FindOrCreateAttribute(father, "AttributeName")
Comp = modulecatalog.GetComponent("SMESH")
FName.SetValue(Comp._get_componentusername())
aPixmap = myStudyBuilder.FindOrCreateAttribute(father, "AttributePixMap")
aPixmap.SetPixMap("ICON_OBJBROWSER_Mesh")
myStudyBuilder.DefineComponentInstance(father,smesh)
mySComponentMesh = father._narrow(SALOMEDS.SComponent)
Tag_HypothesisRoot = 1
Tag_AlgorithmsRoot = 2
Tag_RefOnShape = 1
Tag_RefOnAppliedHypothesis = 2
Tag_RefOnAppliedAlgorithms = 3
Tag_SubMeshOnVertex = 4
Tag_SubMeshOnEdge = 5
Tag_SubMeshOnFace = 6
Tag_SubMeshOnSolid = 7
Tag_SubMeshOnCompound = 8
Tag = {"HypothesisRoot":1,"AlgorithmsRoot":2,"RefOnShape":1,"RefOnAppliedHypothesis":2,"RefOnAppliedAlgorithms":3,"SubMeshOnVertex":4,"SubMeshOnEdge":5,"SubMeshOnFace":6,"SubMeshOnSolid":7,"SubMeshOnCompound":8}
#------------------------------------------------------------
def Init():
pass
#------------------------------------------------------------
def AddNewMesh(IOR):
# VSR: added temporarily - objects are published automatically by the engine
aSO = myStudy.FindObjectIOR( IOR )
if aSO is not None:
return aSO.GetID()
# VSR ######################################################################
res,HypothesisRoot = mySComponentMesh.FindSubObject ( Tag_HypothesisRoot )
if HypothesisRoot is None or res == 0:
HypothesisRoot = myStudyBuilder.NewObjectToTag(mySComponentMesh, Tag_HypothesisRoot)
aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
aName.SetValue("Hypotheses")
aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_hypo.png" )
aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0)
res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
if AlgorithmsRoot is None or res == 0:
AlgorithmsRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
aName.SetValue("Algorithms")
aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_algo.png" )
aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0)
HypothesisRoot = HypothesisRoot._narrow(SALOMEDS.SObject)
newMesh = myStudyBuilder.NewObject(mySComponentMesh)
aPixmap = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_mesh.png" )
anIOR = myStudyBuilder.FindOrCreateAttribute(newMesh, "AttributeIOR")
anIOR.SetValue(IOR)
return newMesh.GetID()
#------------------------------------------------------------
def AddNewHypothesis(IOR):
# VSR: added temporarily - objects are published automatically by the engine
aSO = myStudy.FindObjectIOR( IOR )
if aSO is not None:
return aSO.GetID()
# VSR ######################################################################
res, HypothesisRoot = mySComponentMesh.FindSubObject (Tag_HypothesisRoot)
if HypothesisRoot is None or res == 0:
HypothesisRoot = myStudyBuilder.NewObjectToTag (mySComponentMesh, Tag_HypothesisRoot)
aName = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeName")
aName.SetValue("Hypotheses")
aSelAttr = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0)
aPixmap = myStudyBuilder.FindOrCreateAttribute(HypothesisRoot, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_hypo.png" )
# Add New Hypothesis
newHypo = myStudyBuilder.NewObject(HypothesisRoot)
aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
H = orb.string_to_object(IOR)
aType = H.GetName()
aPixmap.SetPixMap( "mesh_tree_hypo.png_" + aType )
anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
anIOR.SetValue(IOR)
return newHypo.GetID()
#------------------------------------------------------------
def AddNewAlgorithms(IOR):
# VSR: added temporarily - objects are published automatically by the engine
aSO = myStudy.FindObjectIOR( IOR )
if aSO is not None:
return aSO.GetID()
# VSR ######################################################################
res, AlgorithmsRoot = mySComponentMesh.FindSubObject (Tag_AlgorithmsRoot)
if AlgorithmsRoot is None or res == 0:
AlgorithmsRoot = myStudyBuilde.NewObjectToTag (mySComponentMesh, Tag_AlgorithmsRoot)
aName = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeName")
aName.SetValue("Algorithms")
aSelAttr = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0)
aPixmap = myStudyBuilder.FindOrCreateAttribute(AlgorithmsRoot, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_algo.png" )
# Add New Algorithms
newHypo = myStudyBuilder.NewObject(AlgorithmsRoot)
aPixmap = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributePixMap")
aPixmap = anAttr._narrow(SALOMEDS.AttributePixMap)
H = orb.string_to_object(IOR)
aType = H.GetName(); #QString in fact
aPixmap.SetPixMap( "mesh_tree_algo.png_" + aType )
anIOR = myStudyBuilder.FindOrCreateAttribute(newHypo, "AttributeIOR")
anIOR.SetValue(IOR)
return newHypo.GetID()
#------------------------------------------------------------
def SetShape(ShapeEntry, MeshEntry):
SO_MorSM = myStudy.FindObjectID( MeshEntry )
SO_GeomShape = myStudy.FindObjectID( ShapeEntry )
if SO_MorSM is not None and SO_GeomShape is not None :
# VSR: added temporarily - shape reference is published automatically by the engine
res, Ref = SO_MorSM.FindSubObject( Tag_RefOnShape )
if res == 1 :
return
# VSR ######################################################################
SO = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnShape)
myStudyBuilder.Addreference (SO,SO_GeomShape)
#------------------------------------------------------------
def SetHypothesis(Mesh_Or_SubMesh_Entry, Hypothesis_Entry):
SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
SO_Hypothesis = myStudy.FindObjectID( Hypothesis_Entry )
if SO_MorSM is not None and SO_Hypothesis is not None :
#Find or Create Applied Hypothesis root
res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedHypothesis)
if AHR is None or res == 0:
AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedHypothesis)
aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
# The same name as in SMESH_Mesh_i::AddHypothesis() ##################
aName.SetValue("Applied hypotheses")
aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
aSelAttr.SetSelectable(0)
aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_hypo.png" )
# VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
else :
it = myStudy.NewChildIterator(AHR)
while it.More() :
res, Ref = it.Value().ReferencedObject()
if res and Ref is not None and Ref.GetID() == Hypothesis_Entry :
return
it.Next()
# VSR ######################################################################
SO = myStudyBuilder.NewObject(AHR)
myStudyBuilder.Addreference (SO,SO_Hypothesis)
#------------------------------------------------------------
def SetAlgorithms(Mesh_Or_SubMesh_Entry, Algorithms_Entry):
SO_MorSM = myStudy.FindObjectID( Mesh_Or_SubMesh_Entry )
SO_Algorithms = myStudy.FindObjectID( Algorithms_Entry )
if SO_MorSM != None and SO_Algorithms != None :
#Find or Create Applied Algorithms root
res, AHR = SO_MorSM.FindSubObject (Tag_RefOnAppliedAlgorithms)
if AHR is None or res == 0:
AHR = myStudyBuilder.NewObjectToTag (SO_MorSM, Tag_RefOnAppliedAlgorithms)
aName = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeName")
# The same name as in SMESH_Mesh_i::AddHypothesis() ##################
aName.SetValue("Applied algorithms")
aSelAttr = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributeSelectable")
aSelAttr.SetSelectable(0)
aPixmap = myStudyBuilder.FindOrCreateAttribute(AHR, "AttributePixMap")
aPixmap.SetPixMap( "mesh_tree_algo.png" )
# VSR: added temporarily - reference to applied hypothesis is published automatically by the engine
else :
it = myStudy.NewChildIterator(AHR)
while it.More() :
res, Ref = it.Value().ReferencedObject()
if res and Ref is not None and Ref.GetID() == Algorithms_Entry :
return
it.Next()
# VSR ######################################################################
SO = myStudyBuilder.NewObject(AHR)
myStudyBuilder.Addreference (SO,SO_Algorithms)
#------------------------------------------------------------
def UnSetHypothesis( Applied_Hypothesis_Entry ):
SO_Applied_Hypothesis = myStudy.FindObjectID( Applied_Hypothesis_Entry )
if SO_Applied_Hypothesis :
myStudyBuilder.RemoveObject(SO_Applied_Hypothesis)
#------------------------------------------------------------
def AddSubMesh ( SO_Mesh_Entry, SM_IOR, ST):
# VSR: added temporarily - objects are published automatically by the engine
aSO = myStudy.FindObjectIOR( SM_IOR )
if aSO is not None:
return aSO.GetID()
# VSR ######################################################################
SO_Mesh = myStudy.FindObjectID( SO_Mesh_Entry )
if ( SO_Mesh ) :
if ST == ShapeType["COMPSOLID"] :
Tag_Shape = Tag_SubMeshOnSolid
Name = "SubMeshes on Solid"
elif ST == ShapeType["FACE"] :
Tag_Shape = Tag_SubMeshOnFace
Name = "SubMeshes on Face"
elif ST == ShapeType["EDGE"] :
Tag_Shape = Tag_SubMeshOnEdge
Name = "SubMeshes on Edge"
elif ST == ShapeType["VERTEX"] :
Tag_Shape = Tag_SubMeshOnVertex
Name = "SubMeshes on Vertex"
else :
Tag_Shape = Tag_SubMeshOnCompound
Name = "SubMeshes on Compound"
res, SubmeshesRoot = SO_Mesh.FindSubObject (Tag_Shape)
if SubmeshesRoot is None or res == 0:
SubmeshesRoot = myStudyBuilder.NewObjectToTag (SO_Mesh, Tag_Shape)
aName = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeName")
aName.SetValue(Name)
aSelAttr = myStudyBuilder.FindOrCreateAttribute(SubmeshesRoot, "AttributeSelectable")
aSelAttr.SetSelectable(0)
SO = myStudyBuilder.NewObject (SubmeshesRoot)
anIOR = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeIOR")
anIOR.SetValue(SM_IOR)
return SO.GetID()
return None
#------------------------------------------------------------
def AddSubMeshOnShape (Mesh_Entry, GeomShape_Entry, SM_IOR, ST) :
# VSR: added temporarily - objects are published automatically by the engine
aSO = myStudy.FindObjectIOR( SM_IOR )
if aSO is not None:
return aSO.GetID()
# VSR ######################################################################
SO_GeomShape = myStudy.FindObjectID( GeomShape_Entry )
if SO_GeomShape != None :
SM_Entry = AddSubMesh (Mesh_Entry,SM_IOR,ST)
SO_SM = myStudy.FindObjectID( SM_Entry )
if SO_SM != None :
SetShape (GeomShape_Entry, SM_Entry)
return SM_Entry
return None
#------------------------------------------------------------
def SetName(Entry, Name):
SO = myStudy.FindObjectID( Entry )
if SO != None :
aName = myStudyBuilder.FindOrCreateAttribute(SO, "AttributeName")
aName.SetValue(Name)

View File

@ -166,6 +166,14 @@ StdMeshers_FaceSide::StdMeshers_FaceSide(const TopoDS_Face& theFace,
myC3dAdaptor[i].Load( C3d, 0, 0.5 * BRep_Tool::Tolerance( V ));
}
}
else if ( myEdgeLength[i] > DBL_MIN )
{
Handle(Geom_Curve) C3d = BRep_Tool::Curve(myEdge[i],myFirst[i], myLast[i] );
myC3dAdaptor[i].Load( C3d, myFirst[i], myLast[i] );
if ( myEdge[i].Orientation() == TopAbs_REVERSED )
std::swap( myFirst[i], myLast[i] );
}
// reverse a proxy sub-mesh
if ( !theIsForward )
reverseProxySubmesh( myEdge[i] );

View File

@ -1182,7 +1182,7 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
// load boundary nodes into sweeper
bool dummy;
const SMDS_MeshNode* prevN0 = 0, *prevN1 = 0;
std::set< const SMDS_MeshNode* > usedEndNodes;
list< TopoDS_Edge >::const_iterator edge = thePrism.myBottomEdges.begin();
for ( ; edge != thePrism.myBottomEdges.end(); ++edge )
{
@ -1193,9 +1193,8 @@ bool StdMeshers_Prism_3D::compute(const Prism_3D::TPrismTopo& thePrism)
TParam2ColumnMap::iterator u2colIt = u2col->begin(), u2colEnd = u2col->end();
const SMDS_MeshNode* n0 = u2colIt->second[0];
const SMDS_MeshNode* n1 = u2col->rbegin()->second[0];
if ( n0 == prevN0 || n0 == prevN1 ) ++u2colIt;
if ( n1 == prevN0 || n1 == prevN1 ) --u2colEnd;
prevN0 = n0; prevN1 = n1;
if ( !usedEndNodes.insert ( n0 ).second ) ++u2colIt;
if ( !usedEndNodes.insert ( n1 ).second ) --u2colEnd;
for ( ; u2colIt != u2colEnd; ++u2colIt )
sweeper.myBndColumns.push_back( & u2colIt->second );
@ -1627,7 +1626,7 @@ bool StdMeshers_Prism_3D::computeWalls(const Prism_3D::TPrismTopo& thePrism)
TopoDS_Vertex v = myHelper->IthVertex( is2ndV, E );
mesh->GetSubMesh( v )->ComputeStateEngine( SMESH_subMesh::COMPUTE );
const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, meshDS );
newNodes[ is2ndV ? 0 : newNodes.size()-1 ] = (SMDS_MeshNode*) n;
newNodes[ is2ndV ? newNodes.size()-1 : 0 ] = (SMDS_MeshNode*) n;
}
// compute nodes on target EDGEs
@ -3590,10 +3589,10 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
if ( !myHelper->LoadNodeColumns( faceColumns, (*quad)->face, quadBot, meshDS ))
return error(COMPERR_BAD_INPUT_MESH, TCom("Can't find regular quadrangle mesh ")
<< "on a side face #" << MeshDS()->ShapeToIndex( (*quad)->face ));
}
if ( !faceColumns.empty() && (int)faceColumns.begin()->second.size() != VerticalSize() )
return error(COMPERR_BAD_INPUT_MESH, "Different 'vertical' discretization");
}
// edge columns
int id = MeshDS()->ShapeToIndex( *edgeIt );
bool isForward = true; // meaningless for intenal wires
@ -4893,6 +4892,7 @@ bool StdMeshers_Sweeper::projectIntPoints(const vector< gp_XYZ >& fromBndPoin
const vector< gp_XYZ >& toBndPoints,
const vector< gp_XYZ >& fromIntPoints,
vector< gp_XYZ >& toIntPoints,
const double r,
NSProjUtils::TrsfFinder3D& trsf,
vector< gp_XYZ > * bndError)
{
@ -4917,45 +4917,25 @@ bool StdMeshers_Sweeper::projectIntPoints(const vector< gp_XYZ >& fromBndPoin
(*bndError)[ iP ] = toBndPoints[ iP ] - fromTrsf;
}
}
// apply boundary error
if ( bndError && toIntPoints.size() == myTopBotTriangles.size() )
{
for ( size_t iP = 0; iP < toIntPoints.size(); ++iP )
{
const TopBotTriangles& tbTrias = myTopBotTriangles[ iP ];
for ( int i = 0; i < 3; ++i ) // boundary errors at 3 triangle nodes
{
toIntPoints[ iP ] +=
( (*bndError)[ tbTrias.myBotTriaNodes[i] ] * tbTrias.myBotBC[i] * ( 1 - r ) +
(*bndError)[ tbTrias.myTopTriaNodes[i] ] * tbTrias.myTopBC[i] * ( r ));
}
}
}
return true;
}
//================================================================================
/*!
* \brief Add boundary error to ineternal points
*/
//================================================================================
void StdMeshers_Sweeper::applyBoundaryError(const vector< gp_XYZ >& bndPoints,
const vector< gp_XYZ >& bndError1,
const vector< gp_XYZ >& bndError2,
const double r,
vector< gp_XYZ >& intPoints,
vector< double >& int2BndDist)
{
// fix each internal point
const double eps = 1e-100;
for ( size_t iP = 0; iP < intPoints.size(); ++iP )
{
gp_XYZ & intPnt = intPoints[ iP ];
// compute distance from intPnt to each boundary node
double int2BndDistSum = 0;
for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
{
int2BndDist[ iBnd ] = 1 / (( intPnt - bndPoints[ iBnd ]).SquareModulus() + eps );
int2BndDistSum += int2BndDist[ iBnd ];
}
// apply bndError
for ( size_t iBnd = 0; iBnd < bndPoints.size(); ++iBnd )
{
intPnt += bndError1[ iBnd ] * ( 1 - r ) * int2BndDist[ iBnd ] / int2BndDistSum;
intPnt += bndError2[ iBnd ] * r * int2BndDist[ iBnd ] / int2BndDistSum;
}
}
}
//================================================================================
/*!
* \brief Create internal nodes of the prism by computing an affine transformation
@ -4980,6 +4960,10 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
intPntsOfLayer[ zTgt ][ iP ] = intPoint( iP, zTgt );
}
// for each internal column find boundary nodes whose error to use for correction
prepareTopBotDelaunay();
findDelaunayTriangles();
// compute coordinates of internal nodes by projecting (transfroming) src and tgt
// nodes towards the central layer
@ -5006,10 +4990,12 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
}
if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
intPntsOfLayer[ zS-1 ], intPntsOfLayer[ zS ],
zS / ( zSize - 1.),
trsfOfLayer [ zS-1 ], & bndError[ zS-1 ]))
return false;
if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
intPntsOfLayer[ zT+1 ], intPntsOfLayer[ zT ],
zT / ( zSize - 1.),
trsfOfLayer [ zT+1 ], & bndError[ zT+1 ]))
return false;
@ -5048,10 +5034,12 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
}
if (! projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
intPntsOfLayer[ zS-1 ], centerSrcIntPnts,
zS / ( zSize - 1.),
trsfOfLayer [ zS-1 ], & bndError[ zS-1 ]))
return false;
if (! projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
intPntsOfLayer[ zT+1 ], centerTgtIntPnts,
zT / ( zSize - 1.),
trsfOfLayer [ zT+1 ], & bndError[ zT+1 ]))
return false;
@ -5070,24 +5058,7 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
(intPntsOfLayer[ zS-1 ][ iP ] - centerTgtIntPnts[ iP ]).SquareModulus() < tol*tol;
}
// Evaluate an error of boundary points
bool bndErrorIsSmall = true;
for ( size_t iP = 0; ( iP < myBndColumns.size() && bndErrorIsSmall ); ++iP )
{
double sumError = 0;
for ( size_t z = 1; z < zS; ++z ) // loop on layers
sumError += ( bndError[ z-1 ][ iP ].Modulus() +
bndError[ zSize-z ][ iP ].Modulus() );
bndErrorIsSmall = ( sumError < tol );
}
if ( !bndErrorIsSmall && !allowHighBndError )
return false;
// compute final points on the central layer
std::vector< double > int2BndDist( myBndColumns.size() ); // work array of applyBoundaryError()
double r = zS / ( zSize - 1.);
if ( zS == zT )
{
@ -5096,11 +5067,6 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
intPntsOfLayer[ zS ][ iP ] =
( 1 - r ) * centerSrcIntPnts[ iP ] + r * centerTgtIntPnts[ iP ];
}
if ( !bndErrorIsSmall )
{
applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
intPntsOfLayer[ zS ], int2BndDist );
}
}
else
{
@ -5111,17 +5077,9 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
intPntsOfLayer[ zT ][ iP ] =
r * intPntsOfLayer[ zT ][ iP ] + ( 1 - r ) * centerTgtIntPnts[ iP ];
}
if ( !bndErrorIsSmall )
{
applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS+1 ], r,
intPntsOfLayer[ zS ], int2BndDist );
applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT-1 ], r,
intPntsOfLayer[ zT ], int2BndDist );
}
}
centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3
bndErrorIsSmall = true;
//centerIntErrorIsSmall = true; // 3D_mesh_Extrusion_00/A3
if ( !centerIntErrorIsSmall )
{
// Compensate the central error; continue adding projection
@ -5153,9 +5111,11 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
}
projectIntPoints( fromSrcBndPnts, toSrcBndPnts,
fromSrcIntPnts, toSrcIntPnts,
zS / ( zSize - 1.),
trsfOfLayer[ zS+1 ], & srcBndError );
projectIntPoints( fromTgtBndPnts, toTgtBndPnts,
fromTgtIntPnts, toTgtIntPnts,
zT / ( zSize - 1.),
trsfOfLayer[ zT-1 ], & tgtBndError );
// if ( zS == zTgt - 1 )
@ -5186,15 +5146,6 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
zTIntPnts[ iP ] = r * zTIntPnts[ iP ] + ( 1 - r ) * toTgtIntPnts[ iP ];
}
// compensate bnd error
if ( !bndErrorIsSmall )
{
applyBoundaryError( toSrcBndPnts, srcBndError, bndError[ zS+1 ], r,
intPntsOfLayer[ zS ], int2BndDist );
applyBoundaryError( toTgtBndPnts, tgtBndError, bndError[ zT-1 ], r,
intPntsOfLayer[ zT ], int2BndDist );
}
fromSrcBndPnts.swap( toSrcBndPnts );
fromSrcIntPnts.swap( toSrcIntPnts );
fromTgtBndPnts.swap( toTgtBndPnts );
@ -5202,27 +5153,8 @@ bool StdMeshers_Sweeper::ComputeNodesByTrsf( const double tol,
}
} // if ( !centerIntErrorIsSmall )
else if ( !bndErrorIsSmall )
{
zS = zSrc + 1;
zT = zTgt - 1;
for ( ; zS < zT; ++zS, --zT ) // vertical loop on layers
{
for ( size_t iP = 0; iP < myBndColumns.size(); ++iP )
{
toSrcBndPnts[ iP ] = bndPoint( iP, zS );
toTgtBndPnts[ iP ] = bndPoint( iP, zT );
}
// compensate bnd error
applyBoundaryError( toSrcBndPnts, bndError[ zS-1 ], bndError[ zS-1 ], 0.5,
intPntsOfLayer[ zS ], int2BndDist );
applyBoundaryError( toTgtBndPnts, bndError[ zT+1 ], bndError[ zT+1 ], 0.5,
intPntsOfLayer[ zT ], int2BndDist );
}
}
//cout << "centerIntErrorIsSmall = " << centerIntErrorIsSmall<< endl;
// cout << "bndErrorIsSmall = " << bndErrorIsSmall<< endl;
// Create nodes
for ( size_t iP = 0; iP < myIntColumns.size(); ++iP )
@ -5454,3 +5386,78 @@ void StdMeshers_Sweeper::prepareTopBotDelaunay()
myNodeID2ColID.Bind( botNode->GetID(), i );
}
}
//================================================================================
/*!
* \brief For each internal node column, find Delaunay triangles including it
* and Barycentric Coordinates withing the triangles. Fill in myTopBotTriangles
*/
//================================================================================
void StdMeshers_Sweeper::findDelaunayTriangles()
{
const SMDS_MeshNode *botNode, *topNode;
const BRepMesh_Triangle *topTria;
TopBotTriangles tbTrias;
bool checkUV = true;
int nbInternalNodes = myIntColumns.size();
myTopBotTriangles.resize( nbInternalNodes );
myBotDelaunay->InitTraversal( nbInternalNodes );
while (( botNode = myBotDelaunay->NextNode( tbTrias.myBotBC, tbTrias.myBotTriaNodes )))
{
int colID = myNodeID2ColID( botNode->GetID() );
TNodeColumn* column = myIntColumns[ colID ];
// find a Delaunay triangle containing the topNode
topNode = column->back();
gp_XY topUV = myHelper->GetNodeUV( myTopFace, topNode, NULL, &checkUV );
// get a starting triangle basing on that top and bot boundary nodes have same index
topTria = myTopDelaunay->GetTriangleNear( tbTrias.myBotTriaNodes[0] );
topTria = myTopDelaunay->FindTriangle( topUV, topTria,
tbTrias.myTopBC, tbTrias.myTopTriaNodes );
if ( !topTria )
tbTrias.SetTopByBottom();
myTopBotTriangles[ colID ] = tbTrias;
}
#ifdef _DEBUG_
if ( myBotDelaunay->NbVisitedNodes() < nbInternalNodes )
throw SALOME_Exception(LOCALIZED("Not all internal nodes found by Delaunay"));
#endif
myBotDelaunay.reset();
myTopDelaunay.reset();
myNodeID2ColID.Clear();
}
//================================================================================
/*!
* \brief Initialize fields
*/
//================================================================================
StdMeshers_Sweeper::TopBotTriangles::TopBotTriangles()
{
myBotBC[0] = myBotBC[1] = myBotBC[2] = myTopBC[0] = myTopBC[1] = myTopBC[2] = 0.;
myBotTriaNodes[0] = myBotTriaNodes[1] = myBotTriaNodes[2] = 0;
myTopTriaNodes[0] = myTopTriaNodes[1] = myTopTriaNodes[2] = 0;
}
//================================================================================
/*!
* \brief Set top data equal to bottom data
*/
//================================================================================
void StdMeshers_Sweeper::TopBotTriangles::SetTopByBottom()
{
for ( int i = 0; i < 3; ++i )
{
myTopBC[i] = myBotBC[i];
myTopTriaNodes[i] = myBotTriaNodes[0];
}
}

View File

@ -415,21 +415,14 @@ private:
*/
struct StdMeshers_Sweeper
{
// input data
SMESH_MesherHelper* myHelper;
TopoDS_Face myBotFace;
TopoDS_Face myTopFace;
std::vector< TNodeColumn* > myBndColumns; // boundary nodes
// output data
std::vector< TNodeColumn* > myIntColumns; // internal nodes
typedef std::vector< double > TZColumn;
std::vector< TZColumn > myZColumns; // Z distribution of boundary nodes
StdMeshers_ProjectionUtils::DelaunayPtr myTopDelaunay;
StdMeshers_ProjectionUtils::DelaunayPtr myBotDelaunay;
TColStd_DataMapOfIntegerInteger myNodeID2ColID;
bool ComputeNodesByTrsf( const double tol,
const bool allowHighBndError );
@ -447,24 +440,36 @@ private:
gp_XYZ intPoint( int iP, int z ) const
{ return SMESH_TNodeXYZ( (*myIntColumns[ iP ])[ z ]); }
static bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints,
const std::vector< gp_XYZ >& toBndPoints,
const std::vector< gp_XYZ >& fromIntPoints,
std::vector< gp_XYZ >& toIntPoints,
const double r,
StdMeshers_ProjectionUtils::TrsfFinder3D& trsf,
std::vector< gp_XYZ > * bndError);
static void applyBoundaryError(const std::vector< gp_XYZ >& bndPoints,
const std::vector< gp_XYZ >& bndError1,
const std::vector< gp_XYZ >& bndError2,
const double r,
std::vector< gp_XYZ >& toIntPoints,
std::vector< double >& int2BndDist);
typedef std::vector< double > TZColumn;
static void fillZColumn( TZColumn& zColumn,
TNodeColumn& nodes );
void prepareTopBotDelaunay();
void findDelaunayTriangles();
std::vector< TZColumn > myZColumns; // Z distribution of boundary nodes
StdMeshers_ProjectionUtils::DelaunayPtr myTopDelaunay;
StdMeshers_ProjectionUtils::DelaunayPtr myBotDelaunay;
TColStd_DataMapOfIntegerInteger myNodeID2ColID;
// top and bottom Delaulay triangles including an internal column
struct TopBotTriangles
{
double myBotBC[3], myTopBC[3]; // barycentric coordinates of a node within a triangle
int myBotTriaNodes[3], myTopTriaNodes[3]; // indices of boundary columns
TopBotTriangles();
void SetTopByBottom();
};
std::vector< TopBotTriangles> myTopBotTriangles;
};
// ===============================================