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:
eap 2015-08-28 20:03:25 +03:00
parent 0db2de9312
commit 1dd2f82c6d
12 changed files with 531 additions and 279 deletions

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

View File

@ -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>

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 )

View File

@ -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;

View File

@ -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 )

View File

@ -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
{