mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-02-04 07:10:33 +05:00
IPAL52781: Orientation of a wall face created by revolution is wrong
IPAL52850: ConvertToQuadratic creates invalid triangles Regression of imps_09/K0
This commit is contained in:
parent
0db2de9312
commit
1dd2f82c6d
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 1.9 KiB |
@ -48,6 +48,11 @@ The following dialog will appear:
|
||||
|
||||
<li>In this dialog:
|
||||
<ul>
|
||||
<li>Use \a Selection button to specify what you are going to
|
||||
select at a given moment, \b Nodes, \b Edges or \b Faces.
|
||||
\image html image120.png
|
||||
<center><em>"Selection" button</em></center>
|
||||
</li>
|
||||
<li>Specify \b Nodes, \b Edges and \b Faces, which will be extruded, by one
|
||||
of following means:
|
||||
<ul>
|
||||
|
@ -68,16 +68,16 @@ The following dialog will appear:
|
||||
<ul>
|
||||
<li> <b>Angle by Step</b> - the elements are revolved by the
|
||||
specified angle at each step (i.e. for Angle=30 and Number of
|
||||
Steps=2, the elements will be extruded by 30 degrees twice for a
|
||||
total of 30*2=60)
|
||||
\image html revolutionsn2.png "Example of Revolution with Angle by Step"
|
||||
Steps=3, the elements will be extruded by 30 degrees twice for a
|
||||
total of 30*3=90)
|
||||
\image html revolutionsn2.png "Example of Revolution with Angle by Step. Angle=30 and Number of Steps=3"
|
||||
</li>
|
||||
<li> <b>Total Angle</b> - the elements are revolved by the
|
||||
specified angle only once and the number of steps defines the
|
||||
number of iterations (i.e. for Angle=30 and Number of Steps=2,
|
||||
the elements will be revolved by 30/2=15 degrees twice for a
|
||||
number of iterations (i.e. for Angle=30 and Number of Steps=3,
|
||||
the elements will be revolved by 30/3=10 degrees twice for a
|
||||
total of 30).
|
||||
\image html revolutionsn1.png "Example of Revolution with Total Angle"
|
||||
\image html revolutionsn1.png "Example of Revolution with Total Angle. Angle=30 and Number of Steps=3"
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
@ -58,7 +58,7 @@
|
||||
|
||||
#define MYASSERT(val) if (!(val)) throw SALOME_Exception(LOCALIZED("assertion not verified"));
|
||||
|
||||
class SMDS_EXPORT SMDS_Mesh:public SMDS_MeshObject
|
||||
class SMDS_EXPORT SMDS_Mesh : public SMDS_MeshObject
|
||||
{
|
||||
public:
|
||||
friend class SMDS_MeshIDFactory;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,7 @@ class SMDS_MeshVolume;
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
// =========================================================================
|
||||
//
|
||||
@ -90,10 +91,10 @@ class SMDS_EXPORT SMDS_VolumeTool
|
||||
// top and bottom faces are reversed.
|
||||
// Result of IsForward() and methods returning nodes change
|
||||
|
||||
const SMDS_MeshNode** GetNodes() { return myVolumeNodes; }
|
||||
const SMDS_MeshNode** GetNodes() { return &myVolumeNodes[0]; }
|
||||
// Return array of volume nodes
|
||||
|
||||
int NbNodes() { return myVolumeNbNodes; }
|
||||
int NbNodes() { return myVolumeNodes.size(); }
|
||||
// Return array of volume nodes
|
||||
|
||||
double GetSize() const;
|
||||
@ -242,31 +243,42 @@ class SMDS_EXPORT SMDS_VolumeTool
|
||||
static int GetOppFaceIndexOfHex( int faceIndex );
|
||||
// Return index of the opposite face of the hexahedron
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
bool setFace( int faceIndex ) const;
|
||||
|
||||
bool projectNodesToNormal( int faceIndex, double& minProj, double& maxProj ) const;
|
||||
|
||||
const SMDS_MeshElement* myVolume;
|
||||
const SMDS_VtkVolume* myPolyedre;
|
||||
bool myIgnoreCentralNodes;
|
||||
|
||||
bool myVolForward;
|
||||
int myNbFaces;
|
||||
int myVolumeNbNodes;
|
||||
const SMDS_MeshNode** myVolumeNodes;
|
||||
std::vector< int > myPolyIndices;
|
||||
std::vector<const SMDS_MeshNode*> myVolumeNodes;
|
||||
std::vector< int > myPolyIndices; // of a myCurFace
|
||||
std::vector< int > myPolyQuantities;
|
||||
std::vector< int > myPolyFacetOri; // -1-in, +1-out, 0-undef
|
||||
|
||||
mutable bool myExternalFaces;
|
||||
typedef std::pair<int,int> Link;
|
||||
std::map<Link, int> myFwdLinks; // used in IsFaceExternal() to find out myPolyFacetOri
|
||||
|
||||
mutable const int* myAllFacesNodeIndices_F;
|
||||
mutable const int* myAllFacesNodeIndices_RE;
|
||||
mutable const int* myAllFacesNbNodes;
|
||||
mutable int myMaxFaceNbNodes;
|
||||
mutable bool myExternalFaces;
|
||||
|
||||
mutable int myCurFace;
|
||||
mutable int myFaceNbNodes;
|
||||
mutable int* myFaceNodeIndices;
|
||||
mutable const SMDS_MeshNode** myFaceNodes;
|
||||
mutable const int* myAllFacesNodeIndices_F;
|
||||
mutable const int* myAllFacesNodeIndices_RE;
|
||||
mutable const int* myAllFacesNbNodes;
|
||||
mutable int myMaxFaceNbNodes;
|
||||
|
||||
struct SaveFacet;
|
||||
struct Facet
|
||||
{
|
||||
int myIndex;
|
||||
int myNbNodes;
|
||||
int* myNodeIndices;
|
||||
std::vector<const SMDS_MeshNode*> myNodes;
|
||||
};
|
||||
mutable Facet myCurFace;
|
||||
|
||||
};
|
||||
#endif
|
||||
|
@ -12577,6 +12577,11 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
|
||||
TConnectivity tgtNodes;
|
||||
ElemFeatures elemKind( missType ), elemToCopy;
|
||||
|
||||
vector<const SMDS_MeshElement*> presentBndElems;
|
||||
vector<TConnectivity> missingBndElems;
|
||||
vector<int> freeFacets;
|
||||
TConnectivity nodes, elemNodes;
|
||||
|
||||
SMDS_ElemIteratorPtr eIt;
|
||||
if (elements.empty()) eIt = aMesh->elementsIterator(elemType);
|
||||
else eIt = elemSetIterator( elements );
|
||||
@ -12590,18 +12595,24 @@ int SMESH_MeshEditor::MakeBoundaryMesh(const TIDSortedElemSet& elements,
|
||||
// ------------------------------------------------------------------------------------
|
||||
// 1. For an elem, get present bnd elements and connectivities of missing bnd elements
|
||||
// ------------------------------------------------------------------------------------
|
||||
vector<const SMDS_MeshElement*> presentBndElems;
|
||||
vector<TConnectivity> missingBndElems;
|
||||
TConnectivity nodes, elemNodes;
|
||||
presentBndElems.clear();
|
||||
missingBndElems.clear();
|
||||
freeFacets.clear(); nodes.clear(); elemNodes.clear();
|
||||
if ( vTool.Set(elem, /*ignoreCentralNodes=*/true) ) // elem is a volume --------------
|
||||
{
|
||||
vTool.SetExternalNormal();
|
||||
const SMDS_MeshElement* otherVol = 0;
|
||||
for ( int iface = 0, n = vTool.NbFaces(); iface < n; iface++ )
|
||||
{
|
||||
if ( !vTool.IsFreeFace(iface, &otherVol) &&
|
||||
( !aroundElements || elements.count( otherVol )))
|
||||
continue;
|
||||
freeFacets.push_back( iface );
|
||||
}
|
||||
if ( missType == SMDSAbs_Face )
|
||||
vTool.SetExternalNormal();
|
||||
for ( size_t i = 0; i < freeFacets.size(); ++i )
|
||||
{
|
||||
int iface = freeFacets[i];
|
||||
const SMDS_MeshNode** nn = vTool.GetFaceNodes(iface);
|
||||
const size_t nbFaceNodes = vTool.NbFaceNodes (iface);
|
||||
if ( missType == SMDSAbs_Edge ) // boundary edges
|
||||
|
@ -807,6 +807,24 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face&
|
||||
return *( i_proj->second );
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetSurface
|
||||
//purpose : Return a cached ShapeAnalysis_Surface of a FACE
|
||||
//=======================================================================
|
||||
|
||||
Handle(ShapeAnalysis_Surface) SMESH_MesherHelper::GetSurface(const TopoDS_Face& F )
|
||||
{
|
||||
Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
|
||||
int faceID = GetMeshDS()->ShapeToIndex( F );
|
||||
TID2Surface::iterator i_surf = myFace2Surface.find( faceID );
|
||||
if ( i_surf == myFace2Surface.end() && faceID )
|
||||
{
|
||||
Handle(ShapeAnalysis_Surface) surf( new ShapeAnalysis_Surface( surface ));
|
||||
i_surf = myFace2Surface.insert( make_pair( faceID, surf )).first;
|
||||
}
|
||||
return i_surf->second;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
gp_XY AverageUV(const gp_XY& uv1, const gp_XY& uv2) { return ( uv1 + uv2 ) / 2.; }
|
||||
@ -1581,6 +1599,26 @@ const SMDS_MeshNode* SMESH_MesherHelper::GetMediumNode(const SMDS_MeshNode* n1,
|
||||
{
|
||||
F = TopoDS::Face(meshDS->IndexToShape( faceID = pos.first ));
|
||||
uv[0] = GetNodeUV(F,n1,n2, force3d ? 0 : &uvOK[0]);
|
||||
if ( HasDegeneratedEdges() && !force3d ) // IPAL52850 (degen VERTEX not at singularity)
|
||||
{
|
||||
// project middle point to a surface
|
||||
SMESH_TNodeXYZ p1( n1 ), p2( n2 );
|
||||
gp_Pnt pMid = 0.5 * ( p1 + p2 );
|
||||
Handle(ShapeAnalysis_Surface) projector = GetSurface( F );
|
||||
gp_Pnt2d uvMid;
|
||||
if ( uvOK[0] )
|
||||
uvMid = projector->NextValueOfUV( uv[0], pMid, BRep_Tool::Tolerance( F ));
|
||||
else
|
||||
uvMid = projector->ValueOfUV( pMid, getFaceMaxTol( F ));
|
||||
if ( projector->Gap() * projector->Gap() < ( p1 - p2 ).SquareModulus() / 4 )
|
||||
{
|
||||
gp_Pnt pProj = projector->Value( uvMid );
|
||||
n12 = meshDS->AddNode( pProj.X(), pProj.Y(), pProj.Z() );
|
||||
meshDS->SetNodeOnFace( n12, faceID, uvMid.X(), uvMid.Y() );
|
||||
myTLinkNodeMap.insert( make_pair ( link, n12 ));
|
||||
return n12;
|
||||
}
|
||||
}
|
||||
uv[1] = GetNodeUV(F,n2,n1, force3d ? 0 : &uvOK[1]);
|
||||
}
|
||||
else if ( pos.second == TopAbs_EDGE )
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <SMDS_QuadraticEdge.hxx>
|
||||
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
@ -528,6 +529,10 @@ public:
|
||||
GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
|
||||
TopLoc_Location& loc,
|
||||
double tol=0 ) const;
|
||||
/*!
|
||||
* \brief Return a cached ShapeAnalysis_Surface of a FACE
|
||||
*/
|
||||
Handle(ShapeAnalysis_Surface) GetSurface(const TopoDS_Face& F );
|
||||
|
||||
/*!
|
||||
* \brief Check if shape is a degenerated edge or it's vertex
|
||||
@ -731,8 +736,10 @@ public:
|
||||
|
||||
std::map< int, double > myFaceMaxTol;
|
||||
|
||||
typedef std::map< int, Handle(ShapeAnalysis_Surface)> TID2Surface;
|
||||
typedef std::map< int, GeomAPI_ProjectPointOnSurf* > TID2ProjectorOnSurf;
|
||||
typedef std::map< int, GeomAPI_ProjectPointOnCurve* > TID2ProjectorOnCurve;
|
||||
TID2Surface myFace2Surface;
|
||||
TID2ProjectorOnSurf myFace2Projector;
|
||||
TID2ProjectorOnCurve myEdge2Projector;
|
||||
|
||||
|
@ -3619,8 +3619,8 @@ class Mesh:
|
||||
## Creates 2D mesh as skin on boundary faces of a 3D mesh
|
||||
# @return TRUE if operation has been completed successfully, FALSE otherwise
|
||||
# @ingroup l2_modif_edit
|
||||
def Make2DMeshFrom3D(self):
|
||||
return self.editor. Make2DMeshFrom3D()
|
||||
def Make2DMeshFrom3D(self):
|
||||
return self.editor.Make2DMeshFrom3D()
|
||||
|
||||
## Creates missing boundary elements
|
||||
# @param elements - elements whose boundary is to be checked:
|
||||
@ -4910,6 +4910,8 @@ class Mesh:
|
||||
fun = self._getFunctor( funType )
|
||||
if fun:
|
||||
if meshPart:
|
||||
if hasattr( meshPart, "SetMesh" ):
|
||||
meshPart.SetMesh( self.mesh ) # set mesh to filter
|
||||
hist = fun.GetLocalHistogram( 1, False, meshPart )
|
||||
else:
|
||||
hist = fun.GetHistogram( 1, False )
|
||||
|
@ -410,7 +410,7 @@ const vector<UVPtStruct>& StdMeshers_FaceSide::GetUVPtStruct(bool isXConst,
|
||||
if ( u2node.empty() ) return myPoints;
|
||||
|
||||
const SMDS_MeshNode* node;
|
||||
if ( IsClosed() )
|
||||
if ( IsClosed() && !proxySubMesh[0] )
|
||||
node = u2node.begin()->second;
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user