-// Copyright (C) 2003 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.
-//
-// 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
-//
+// Copyright (C) 2007-2014 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 : SMESH_Pattern.hxx
// Created : Mon Aug 2 10:30:00 2004
// Author : Edward AGAPOV (eap)
-using namespace std;
-
#include "SMESH_Pattern.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshFace.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_Group.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESHDS_SubMesh.hxx"
+#include "SMESH_Block.hxx"
+#include "SMESH_Mesh.hxx"
+#include "SMESH_MeshAlgos.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+
#include <BRepAdaptor_Curve.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <Bnd_Box.hxx>
#include <Bnd_Box2d.hxx>
#include <ElSLib.hxx>
+#include <Extrema_ExtPC.hxx>
#include <Extrema_GenExtPS.hxx>
#include <Extrema_POnSurf.hxx>
#include <Geom2d_Curve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
-//#include <IntAna2d_AnaIntersection.hxx>
+#include <Precision.hxx>
#include <TopAbs_ShapeEnum.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <gp_XY.hxx>
#include <gp_XYZ.hxx>
-#include "SMDS_EdgePosition.hxx"
-#include "SMDS_FacePosition.hxx"
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshFace.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMESHDS_Group.hxx"
-#include "SMESHDS_Mesh.hxx"
-#include "SMESHDS_SubMesh.hxx"
-#include "SMESH_Block.hxx"
-#include "SMESH_Mesh.hxx"
-#include "SMESH_MeshEditor.hxx"
-#include "SMESH_subMesh.hxx"
+#include <Basics_OCCTVersion.hxx>
+#include <Basics_Utils.hxx>
#include "utilities.h"
using namespace std;
{
MESSAGE("Load( file ) ");
+ Kernel_Utils::Localizer loc;
+
// file structure:
// ! This is a comment
MESSAGE(" Too few points ");
return setErrorCode( ERR_READ_TOO_FEW_POINTS );
}
-
+
// read the rest points
int iPoint;
for ( iPoint = 1; iPoint < nbPoints; iPoint++ )
bool SMESH_Pattern::Save (ostream& theFile)
{
MESSAGE(" ::Save(file) " );
+
+ Kernel_Utils::Localizer loc;
+
if ( !IsLoaded() ) {
MESSAGE(" Pattern not loaded ");
return setErrorCode( ERR_SAVE_NOT_LOADED );
}
theFile << endl;
-
+
return setErrorCode( ERR_OK );
}
}
double u, v, minVal = DBL_MAX;
for ( int i = theProjectorPS.NbExt(); i > 0; i-- )
+#if OCC_VERSION_LARGE > 0x06040000 // Porting to OCCT6.5.1
+ if ( theProjectorPS.SquareDistance( i ) < minVal ) {
+ minVal = theProjectorPS.SquareDistance( i );
+#else
if ( theProjectorPS.Value( i ) < minVal ) {
minVal = theProjectorPS.Value( i );
+#endif
theProjectorPS.Point( i ).Parameter( u, v );
}
return gp_XY( u, v );
while ( nIt->more() )
{
const SMDS_MeshNode* node = smdsNode( nIt->next() );
- SMDS_PositionPtr pos = node->GetPosition();
- if ( !pos || !pos->GetShapeId() ) {
+ if (node->getshapeId() <1) {
return false;
}
}
bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
const TopoDS_Face& theFace,
- bool theProject)
+ bool theProject,
+ TopoDS_Vertex the1stVertex)
{
MESSAGE(" ::Load(face) " );
Clear();
SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
SMESHDS_SubMesh * fSubMesh = aMeshDS->MeshElements( theFace );
+ const bool isQuadMesh = aMeshDS->GetMeshInfo().NbFaces( ORDER_QUADRATIC );
SMESH_MesherHelper helper( *theMesh );
helper.SetSubShape( theFace );
TopoDS_Face face = TopoDS::Face( theFace.Oriented( TopAbs_FORWARD ));
- // check that face is not closed
+ // check if face is closed
bool isClosed = helper.HasSeam();
- TopoDS_Vertex bidon;
list<TopoDS_Edge> eList;
list<TopoDS_Edge>::iterator elIt;
- SMESH_Block::GetOrderedEdges( face, bidon, eList, myNbKeyPntInBoundary );
+ SMESH_Block::GetOrderedEdges( face, eList, myNbKeyPntInBoundary, the1stVertex );
// check that requested or needed projection is possible
bool isMainShape = theMesh->IsMainShape( face );
{
myElemPointIDs.push_back( TElemDef() );
TElemDef& elemPoints = myElemPointIDs.back();
- SMDS_ElemIteratorPtr nIt = (*fIt)->nodesIterator();
- while ( nIt->more() )
+ int nbNodes = (*fIt)->NbCornerNodes();
+ for ( int i = 0;i < nbNodes; ++i )
{
- const SMDS_MeshElement* node = nIt->next();
- TNodePointIDMap::iterator nIdIt = nodePointIDMap.find( node );
- if ( nIdIt == nodePointIDMap.end() )
+ const SMDS_MeshElement* node = (*fIt)->GetNode( i );
+ TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
+ if ( nIdIt->second == -1 )
{
elemPoints.push_back( iPoint );
- nodePointIDMap.insert( make_pair( node, iPoint++ ));
+ nIdIt->second = iPoint++;
}
else
elemPoints.push_back( (*nIdIt).second );
// vertices
for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) {
+ int nbV = myShapeIDMap.Extent();
myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- if ( BRep_Tool::IsClosed( *elIt, theFace ) )
- myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));
- SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt );
- if ( eSubMesh )
+ bool added = ( nbV < myShapeIDMap.Extent() );
+ if ( !added ) { // vertex encountered twice
+ // a seam vertex have two corresponding key points
+ myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ).Reversed());
+ ++nbNodes;
+ }
+ if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ))
nbNodes += eSubMesh->NbNodes() + 1;
}
// edges
TopoDS_Edge & edge = *elIt;
list< TPoint* > & ePoints = getShapePoints( edge );
double f, l;
- Handle(Geom2d_Curve) C2d;
- if ( !theProject )
- C2d = BRep_Tool::CurveOnSurface( edge, face, f, l );
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface( edge, face, f, l );
bool isForward = ( edge.Orientation() == TopAbs_FORWARD );
TopoDS_Shape v1 = TopExp::FirstVertex( edge, true ); // always FORWARD
v2.Reverse();
// on closed face we must have REVERSED some of seam vertices
- bool isSeam = helper.IsSeamShape( edge );
if ( isClosed ) {
- if ( isSeam ) { // reverse on reversed SEAM edge
- if ( !isForward ) {
+ if ( helper.IsSeamShape( edge ) ) {
+ if ( helper.IsRealSeam( edge ) && !isForward ) {
+ // reverse on reversed SEAM edge
v1.Reverse();
v2.Reverse();
}
}
- else { // on CLOSED edge
+ else { // on CLOSED edge (i.e. having one vertex with different orienations)
for ( int is2 = 0; is2 < 2; ++is2 ) {
TopoDS_Shape & v = is2 ? v2 : v1;
- if ( helper.IsSeamShape( v ) ) {
+ if ( helper.IsRealSeam( v ) ) {
// reverse or not depending on orientation of adjacent seam
TopoDS_Edge seam;
list<TopoDS_Edge>::iterator eIt2 = elIt;
// loop on nodes of an edge: sort them by param on edge
typedef map < double, const SMDS_MeshNode* > TParamNodeMap;
TParamNodeMap paramNodeMap;
+ int nbMeduimNodes = 0;
SMDS_NodeIteratorPtr nIt = eSubMesh->GetNodes();
while ( nIt->more() )
{
- const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) {
+ ++nbMeduimNodes;
+ continue;
+ }
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = epos->GetUParameter();
- paramNodeMap.insert( TParamNodeMap::value_type( u, node ));
+ paramNodeMap.insert( make_pair( u, node ));
}
+ if ( paramNodeMap.size() != eSubMesh->NbNodes() ) {
+ // wrong U on edge, project
+ Extrema_ExtPC proj;
+ BRepAdaptor_Curve aCurve( edge );
+ proj.Initialize( aCurve, f, l );
+ paramNodeMap.clear();
+ nIt = eSubMesh->GetNodes();
+ for ( int iNode = 0; nIt->more(); ++iNode ) {
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face ))
+ continue;
+ proj.Perform( gp_Pnt( node->X(), node->Y(), node->Z()));
+ double u = 0;
+ if ( proj.IsDone() ) {
+ for ( int i = 1, nb = proj.NbExt(); i <= nb; ++i )
+ if ( proj.IsMin( i )) {
+ u = proj.Point( i ).Parameter();
+ break;
+ }
+ } else {
+ u = isForward ? iNode : eSubMesh->NbNodes() - iNode;
+ }
+ paramNodeMap.insert( make_pair( u, node ));
+ }
+
+ //rnv : To fix the bug IPAL21999 Pattern Mapping - New - collapse of pattern mesh
+ if ( paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes )
+ return setErrorCode(ERR_UNEXPECTED);
+ }
+
// put U in [0,1] so that the first key-point has U==0
+ bool isSeam = helper.IsRealSeam( edge );
double du = l - f;
TParamNodeMap::iterator unIt = paramNodeMap.begin();
TParamNodeMap::reverse_iterator unRIt = paramNodeMap.rbegin();
SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
while ( nIt->more() )
{
- const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face ))
+ continue;
nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* p = &myPoints[ iPoint++ ];
fPoints.push_back( p );
p->myInitUV = project( node, projector );
else {
const SMDS_FacePosition* pos =
- static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_FacePosition*>(node->GetPosition());
p->myInitUV.SetCoord( pos->GetUParameter(), pos->GetVParameter() );
}
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
}
// load elements
+ TNodePointIDMap::iterator n_id, not_found = closeNodePointIDMap.end();
SMDS_ElemIteratorPtr elemIt = fSubMesh->GetElements();
while ( elemIt->more() )
{
while ( nIt->more() )
{
const SMDS_MeshNode* node = smdsNode( nIt->next() );
- iPoint = nodePointIDMap[ node ]; // point index of interest
+ n_id = nodePointIDMap.find( node );
+ if ( n_id == nodePointIDMap.end() )
+ continue; // medium node
+ iPoint = n_id->second; // point index of interest
// for a node on a seam edge there are two points
- TNodePointIDMap::iterator n_id = closeNodePointIDMap.end();
- if ( helper.IsSeamShape( node->GetPosition()->GetShapeId() ))
- n_id = closeNodePointIDMap.find( node );
- if ( n_id != closeNodePointIDMap.end() )
+ if ( helper.IsRealSeam( node->getshapeId() ) &&
+ ( n_id = closeNodePointIDMap.find( node )) != not_found )
{
TPoint & p1 = myPoints[ iPoint ];
TPoint & p2 = myPoints[ n_id->second ];
// find node not on a seam edge
while ( nIt2->more() && !notSeamNode ) {
const SMDS_MeshNode* n = smdsNode( nIt2->next() );
- if ( !helper.IsSeamShape( n->GetPosition()->GetShapeId() ))
+ if ( !helper.IsSeamShape( n->getshapeId() ))
notSeamNode = n;
}
gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode );
}
}
}
+ myPoints.resize( nodePointIDMap.size() + closeNodePointIDMap.size() );
myIsBoundaryPointsFound = true;
}
// resUV = loc1 * len2 / ( len1 + len2 ) + loc2 * len1 / ( len1 + len2 );
// return true;
-
+
// gp_Lin2d line1( uv11, uv12 - uv11 );
// gp_Lin2d line2( uv21, uv22 - uv21 );
// double angle = Abs( line1.Angle( line2 ) );
// inter.Perform( line1, line2 );
// interUV = inter.Point(1).Value();
// resUV += interUV.XY();
-
+
// resUV /= 2.;
// }
if ( isDeformed ) {
const list< TPoint* > & bndPoints = * bndIt;
TPoint* prevP = bndPoints.back(); // this is the first point
list< TPoint* >::const_iterator pIt = bndPoints.begin();
- bool coincPrev = false;
+ bool coincPrev = false;
// loop on the edge-points
for ( ; pIt != bndPoints.end(); pIt++ )
{
maxLen2 = Max( maxLen2, ( n[1]->myUV - n[2]->myUV ).SquareModulus() );
}
maxLen2 = Max( maxLen2, ( n[2]->myUV - node->myUV ).SquareModulus() );
- minDiag = sqrt( maxLen2 ) * PI / 60.; // ~ maxLen * Sin( 3 deg )
+ minDiag = sqrt( maxLen2 ) * M_PI / 60.; // ~ maxLen * Sin( 3 deg )
}
// check if newUV is behind 3 dirs: n[0]-n[1], n[1]-n[2] and n[0]-n[2]
gp_XY uv1, uv2 = node->myUV;
for ( i = isTriangle ? 2 : 0; i < 3; i++ ) // mark not computed vectors
if ( wasOk[i] )
- moveVec[ i ].SetCoord( 1, 2e100); // not use this vector
+ moveVec[ i ].SetCoord( 1, 2e100); // not use this vector
while ( !isOldOk ) {
// find the least moveVec
int i, iMin = 4;
aNorm[1-iDir].Normalize();
double r = Abs ( ratio[iDir] - 0.5 ) * 2.0; // [0,1] - distance from the middle
r *= r;
-
+
node->myDir[iDir] = //aTgt[iDir];
aNorm[1-iDir] * r + aTgt[iDir] * ( 1. - r );
}
double initAngle = initTgt1.Angle( initTgt2 );
double angle = node->myDir[0].Angle( node->myDir[1] );
if ( reversed ) angle = -angle;
- if ( initAngle > angle && initAngle - angle > PI / 2.1 ) {
+ if ( initAngle > angle && initAngle - angle > M_PI / 2.1 ) {
// find a close internal node
TIsoNode* nClose = 0;
list< TIsoNode* > testNodes;
for ( nIt = startNodes.begin(); nIt != startNodes.end(); nIt++ )
{
- TIsoNode* prevN[2], *node = *nIt;
+ TIsoNode *node = *nIt;
if ( node->IsUVComputed() || !node->IsMovable() )
continue;
gp_XY newUV( 0, 0 ), sumDir( 0, 0 );
newUV += prevNode1->myUV + dir * step[ iDir ];
}
sumDir += dir;
- prevN[ iDir ] = prevNode1;
nbComp++;
}
}
}
internNodes.push_back( node );
}
-
+
// Move nodes
static int maxNbIter = 100;
int nbNodeMove = 0;
if ( !useNbMoveNode )
maxNbIter = ( maxNbIter < 0 ) ? 100 : -1;
-#endif
+#endif
double maxMove;
int nbIter = 0;
do {
}
// define ratio
bool ok = true; // <- stupid fix TO AVOID PB OF NODES WITH NULL BND NODES
- double locR[2] = { 0, 0 };
+// double locR[2] = { 0, 0 };
for ( iDir = 0; iDir < 2; iDir++ )
{
const int iCoord = 2 - iDir; // coord changing along an isoline
double par3 = bndNode2->myInitUV.Coord( iCoord );
double r = ( par2 - par1 ) / ( par3 - par1 );
r = Abs ( r - 0.5 ) * 2.0; // [0,1] - distance from the middle
- locR[ iDir ] = ( 1 - r * r ) * 0.25;
+// locR[ iDir ] = ( 1 - r * r ) * 0.25;
}
//locR[0] = locR[1] = 0.25;
// intersect the 2 lines and move a node
}
}
}
-
-
+
return true;
}
int eID = theFirstEdgeID;
for ( iE = 0; iE < nbEdges; iE++ )
maxNbPnt = Max ( maxNbPnt, getShapePoints( eID++ ).size() );
-
+
// compute bnd boxes
TopoDS_Face face = TopoDS::Face( myShape );
Bnd_Box2d bndBox, eBndBox;
bndBox.Get( minPar[0], minPar[1], maxPar[0], maxPar[1] );
eBndBox.Get( eMinPar[0], eMinPar[1], eMaxPar[0], eMaxPar[1] );
#ifdef DBG_SETFIRSTEDGE
- cout << "EDGES: X: " << eMinPar[0] << " - " << eMaxPar[0] << " Y: "
- << eMinPar[1] << " - " << eMaxPar[1] << endl;
+ MESSAGE ( "EDGES: X: " << eMinPar[0] << " - " << eMaxPar[0] << " Y: "
+ << eMinPar[1] << " - " << eMaxPar[1] );
#endif
for ( int iC = 1, i = 0; i < 2; iC++, i++ ) // loop on 2 coordinates
{
for ( iE = 0 ; iE < nbEdges; iE++ )
{
#ifdef DBG_SETFIRSTEDGE
- cout << " VARIANT " << iE << endl;
+ MESSAGE ( " VARIANT " << iE );
#endif
// evaluate the distance between UV computed by the 2 methods:
// by isos intersection ( myXYZ ) and by edge p-curves ( myUV )
TPoint* p = (*pIt);
dist += ( p->myUV - gp_XY( p->myXYZ.X(), p->myXYZ.Y() )).SquareModulus();
#ifdef DBG_SETFIRSTEDGE
- cout << " ISO : ( " << p->myXYZ.X() << ", "<< p->myXYZ.Y() << " ) PCURVE : ( " <<
- p->myUV.X() << ", " << p->myUV.Y() << ") " << endl;
+ MESSAGE ( " ISO : ( " << p->myXYZ.X() << ", "<< p->myXYZ.Y() << " ) PCURVE : ( " <<
+ p->myUV.X() << ", " << p->myUV.Y() << ") " );
#endif
}
}
#ifdef DBG_SETFIRSTEDGE
- cout << "dist -- " << dist << endl;
+ MESSAGE ( "dist -- " << dist );
#endif
if ( dist < minDist ) {
minDist = dist;
bndIndWirePosMap.insert( TIntWirePosMap::value_type( bIndex, wlIt ));
}
- // Treat each wire
+ // Treat each wire
TIntWirePosMap::iterator bIndWPosIt = bndIndWirePosMap.begin();
eID = theFirstEdgeID;
// choose the best first edge of a wire
setFirstEdge( wire, eID );
-
+
// compute eventual UV and fill theEdgesPointsList
theEdgesPointsList.push_back( list< TPoint* >() );
list< TPoint* > & edgesPoints = theEdgesPointsList.back();
list< TopoDS_Edge > eList;
list< int > nbVertexInWires;
- int nbWires = SMESH_Block::GetOrderedEdges( face, theVertexOnKeyPoint1, eList, nbVertexInWires);
+ int nbWires = SMESH_Block::GetOrderedEdges( face, eList, nbVertexInWires, theVertexOnKeyPoint1);
if ( !theVertexOnKeyPoint1.IsSame( TopExp::FirstVertex( eList.front(), true )))
{
MESSAGE( " theVertexOnKeyPoint1 not found in the outer wire ");
list<TopoDS_Edge>::iterator elIt = eList.begin();
for ( ; elIt != eList.end(); elIt++ ) {
myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- if ( BRep_Tool::IsClosed( *elIt, theFace ) )
- myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));
+ bool isClosed1 = BRep_Tool::IsClosed( *elIt, theFace );
+ // BEGIN: jfa for bug 0019943
+ if (isClosed1) {
+ isClosed1 = false;
+ for (TopExp_Explorer expw (theFace, TopAbs_WIRE); expw.More() && !isClosed1; expw.Next()) {
+ const TopoDS_Wire& wire = TopoDS::Wire(expw.Current());
+ int nbe = 0;
+ for (BRepTools_WireExplorer we (wire, theFace); we.More() && !isClosed1; we.Next()) {
+ if (we.Current().IsSame(*elIt)) {
+ nbe++;
+ if (nbe == 2) isClosed1 = true;
+ }
+ }
+ }
+ }
+ // END: jfa for bug 0019943
+ if (isClosed1)
+ myShapeIDMap.Add( TopExp::LastVertex( *elIt, true ));// vertex orienation is REVERSED
}
int nbVertices = myShapeIDMap.Extent();
myShapeIDMap.Add( face );
- if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent()/* + nbSeamShapes*/ ) {
+ if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
MESSAGE( myShapeIDToPointsMap.size() <<" != " << myShapeIDMap.Extent());
return setErrorCode( ERR_APPLF_INTERNAL_EEROR );
}
}
// find boundary - wire correspondence for several wires of same size
-
+
id1 = nbVertices + nbEdgesInOuterWire + 1;
wlIt = wireList.begin();
while ( wlIt != wireList.end() )
}
// add well-ordered edges to eList
-
+
for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ )
{
list< TopoDS_Edge >& wire = (*wlIt);
for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
myShapeIDMap.Add( *elIt );
myShapeIDMap.Add( face );
-
+
} // there are inner wires
// Compute XYZ of on-edge points
}
// check nb of nodes
- if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) {
- MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() );
+ const int nbFaceNodes = theFace->NbCornerNodes();
+ if ( nbFaceNodes != myNbKeyPntInBoundary.front() ) {
+ MESSAGE( myKeyPointIDs.size() << " != " << nbFaceNodes );
return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
}
list< const SMDS_MeshNode* > nodes;
list< const SMDS_MeshNode* >::iterator n = nodes.end();
- SMDS_ElemIteratorPtr noIt = theFace->nodesIterator();
+ SMDS_NodeIteratorPtr noIt = theFace->nodeIterator();
int iSub = 0;
- while ( noIt->more() ) {
- const SMDS_MeshNode* node = smdsNode( noIt->next() );
+ while ( noIt->more() && iSub < nbFaceNodes ) {
+ const SMDS_MeshNode* node = noIt->next();
nodes.push_back( node );
if ( iSub++ == theNodeIndexOnKeyPoint1 )
n = --nodes.end();
nodes.splice( nodes.end(), nodes, nodes.begin(), n );
}
list< gp_XYZ > xyzList;
- myOrderedNodes.resize( theFace->NbNodes() );
+ myOrderedNodes.resize( nbFaceNodes );
for ( iSub = 0, n = nodes.begin(); n != nodes.end(); ++n ) {
- xyzList.push_back( gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() ));
+ xyzList.push_back( SMESH_TNodeXYZ( *n ));
myOrderedNodes[ iSub++] = *n;
}
{
gp_XYZ& xyz1 = *xyzIt++;
gp_XYZ& xyz2 = ( xyzIt != xyzList.end() ) ? *xyzIt : xyzList.front();
-
+
list< TPoint* > & ePoints = getShapePoints( iSub );
ePoints.back()->myInitU = 1.0;
list< TPoint* >::const_iterator pIt = ++ePoints.begin();
myXYZ.resize( myPoints.size() * theFaces.size(), undefinedXYZ() );
myElements.reserve( theFaces.size() );
- // to find point index
- map< TPoint*, int > pointIndex;
- for ( int i = 0; i < myPoints.size(); i++ )
- pointIndex.insert( make_pair( & myPoints[ i ], i ));
-
int ind1 = 0; // lowest point index for a face
// meshed geometry
TopoDS_Shape shape;
// int shapeID = 0;
-// SMESH_MeshEditor editor( theMesh );
+// SMESH_MeshEditor editor( theMesh );
// apply to each face in theFaces set
set<const SMDS_MeshFace*>::iterator face = theFaces.begin();
}
// put points on links to myIdsOnBoundary,
// they will be used to sew new elements on adjacent refined elements
- int nbNodes = (*face)->NbNodes(), eID = nbNodes + 1;
+ int nbNodes = (*face)->NbCornerNodes(), eID = nbNodes + 1;
for ( int i = 0; i < nbNodes; i++ )
{
list< TPoint* > & linkPoints = getShapePoints( eID++ );
const SMDS_MeshNode* n1 = myOrderedNodes[ i ];
- const SMDS_MeshNode* n2 = myOrderedNodes[ i + 1 == nbNodes ? 0 : i + 1 ];
+ const SMDS_MeshNode* n2 = myOrderedNodes[( i+1 ) % nbNodes ];
// make a link and a node set
TNodeSet linkSet, node1Set;
linkSet.insert( n1 );
list< TPoint* >::iterator p = linkPoints.begin();
{
// map the first link point to n1
- int nId = pointIndex[ *p ] + ind1;
+ int nId = ( *p - &myPoints[0] ) + ind1;
myXYZIdToNodeMap[ nId ] = n1;
list< list< int > >& groups = myIdsOnBoundary[ node1Set ];
groups.push_back(list< int > ());
list< int >& indList = groups.back();
// add points to the map excluding the end points
for ( p++; *p != linkPoints.back(); p++ )
- indList.push_back( pointIndex[ *p ] + ind1 );
+ indList.push_back( ( *p - &myPoints[0] ) + ind1 );
}
ind1 += myPoints.size();
}
myIs2D = false;
SMESHDS_SubMesh * aSubMesh;
+ const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC );
+
// load shapes in myShapeIDMap
SMESH_Block block;
TopoDS_Vertex v1, v2;
// store a node and a point
while ( nIt->more() ) {
const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Volume ))
+ continue;
nodePointIDMap.insert( make_pair( node, iPoint ));
if ( block.IsVertexID( shapeID ))
myKeyPointIDs.push_back( iPoint );
nIt = aSubMesh->GetNodes();
for ( ; nIt->more(); pIt++ )
{
- const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+ continue;
const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition());
double u = ( epos->GetUParameter() - f ) / ( l - f );
(*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u );
}
{
SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements();
while ( elemIt->more() ) {
- SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator();
+ const SMDS_MeshElement* elem = elemIt->next();
myElemPointIDs.push_back( TElemDef() );
TElemDef& elemPoints = myElemPointIDs.back();
- while ( nIt->more() )
- elemPoints.push_back( nodePointIDMap[ nIt->next() ]);
+ int nbNodes = elem->NbCornerNodes();
+ for ( int i = 0;i < nbNodes; ++i )
+ elemPoints.push_back( nodePointIDMap[ elem->GetNode( i )]);
}
}
Bnd_Box box;
TNodeSet::const_iterator n = nodes.begin();
for ( ; n != nodes.end(); ++n )
- box.Add( gp_Pnt( (*n)->X(), (*n)->Y(), (*n)->Z() ));
+ box.Add( gp_Pnt( SMESH_TNodeXYZ( *n )));
double x, y, z, X, Y, Z;
box.Get( x, y, z, X, Y, Z );
gp_Pnt p( x, y, z ), P( X, Y, Z );
bool unite = ( uniteGroups && nodes.size() == 2 );
map< double, int > distIndMap;
const SMDS_MeshNode* node = *nodes.begin();
- gp_Pnt P( node->X(), node->Y(), node->Z() );
+ gp_Pnt P = SMESH_TNodeXYZ( node );
// compare points, replace indices
while (true)
{
const SMDS_MeshElement* face =
- SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
+ SMESH_MeshAlgos::FindFaceInSet( n1, n2, elemSet, avoidSet );
if ( face )
{
avoidSet.insert ( face );
vector<int>& theQuantity)
{
bool makePoly = false;
-// cout << "FROM FACE NODES: " <<endl;
-// for ( int i = 0; i < theNbBndNodes; ++i )
-// cout << theBndNodes[ i ];
- set< const SMDS_MeshNode* > bndNodeSet;
- for ( int i = 0; i < theNbBndNodes; ++i )
- bndNodeSet.insert( theBndNodes[ i ]);
+ set< const SMDS_MeshNode* > bndNodeSet( theBndNodes, theBndNodes + theNbBndNodes);
map< TNodeSet, list< list< int > > >::iterator nn_IdList;
if ( !myIs2D ) { // for 2D, merge only edges
nn_IdList = myIdsOnBoundary.find( bndNodeSet );
if ( nn_IdList != myIdsOnBoundary.end() ) {
- makePoly = true;
list< int > & faceIds = nn_IdList->second.front();
- ids.insert( faceIds.begin(), faceIds.end() );
+ if ( !faceIds.empty() ) {
+ makePoly = true;
+ ids.insert( faceIds.begin(), faceIds.end() );
+ }
}
}
- //bool hasIdsInFace = !ids.empty();
// add ids on links and bnd nodes
int lastFreeId = Max( myXYZIdToNodeMap.rbegin()->first, theNodes.size() );
bndId = nn_IdList->second.front().front();
ids.insert( bndId );
}
- else
+ else {
myXYZIdToNodeMap.insert( make_pair( bndId, theBndNodes[ iN ] ));
+ }
faceDef.push_back( bndId );
// add ids on a link
TNodeSet linkNodes;
linkNodes.insert( theBndNodes[ iN ]);
- linkNodes.insert( theBndNodes[ iN + 1 == theNbBndNodes ? 0 : iN + 1 ]);
+ linkNodes.insert( theBndNodes[ (iN + 1) % theNbBndNodes] );
nn_IdList = myIdsOnBoundary.find( linkNodes );
if ( nn_IdList != myIdsOnBoundary.end() ) {
- makePoly = true;
list< int > & linkIds = nn_IdList->second.front();
- ids.insert( linkIds.begin(), linkIds.end() );
- if ( isReversed( theBndNodes[ iN ], linkIds ))
- faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() );
- else
- faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() );
+ if ( !linkIds.empty() )
+ {
+ makePoly = true;
+ ids.insert( linkIds.begin(), linkIds.end() );
+ if ( isReversed( theBndNodes[ iN ], linkIds ))
+ faceDef.insert( faceDef.end(), linkIds.begin(), linkIds.end() );
+ else
+ faceDef.insert( faceDef.end(), linkIds.rbegin(), linkIds.rend() );
+ }
}
}
{
if ( !checkedVolDefs.insert( *pIdList ).second )
continue; // skip already checked volume definition
- vector< int > idVec;
- idVec.reserve( (*pIdList)->size() );
- idVec.insert( idVec.begin(), (*pIdList)->begin(), (*pIdList)->end() );
+ vector< int > idVec( (*pIdList)->begin(), (*pIdList)->end() );
// loop on face defs of a volume
SMDS_VolumeTool::VolumeType volType = vol.GetType( idVec.size() );
if ( volType == SMDS_VolumeTool::UNKNOWN )
}
if ( !defsAdded ) {
theQuantity.push_back( faceDef.size() );
- theFaceDefs.splice( theFaceDefs.end(), faceDef, faceDef.begin(), faceDef.end() );
+ theFaceDefs.splice( theFaceDefs.end(), faceDef );
}
return makePoly;
bool removed = false;
if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMeshContaining( theShape ))
{
- if ( aSubMesh->GetSubMeshDS() ) {
- removed =
- aSubMesh->GetSubMeshDS()->NbElements() || aSubMesh->GetSubMeshDS()->NbNodes();
+ removed = !aSubMesh->IsEmpty();
+ if ( removed )
aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
- }
}
else {
SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
// coordinates computed by either of Apply...() methods
// WARNING : StdMeshers_Projection_... relies on MakeMesh() behavior: that
// it does not care of nodes and elements already existing on
-// subshapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
+// sub-shapes. DO NOT MERGE them or modify also StdMeshers_Projection_..
//=======================================================================
bool SMESH_Pattern::MakeMesh(SMESH_Mesh* theMesh,
myXYZ[ i ].Y(),
myXYZ[ i ].Z());
}
- }
+ if ( theMesh->HasShapeToMesh() )
+ {
+ // set nodes on EDGEs (IMP 22368)
+ SMESH_MesherHelper helper( *theMesh );
+ helper.ToFixNodeParameters( true );
+ map< TNodeSet, list< list< int > > >::iterator idListIt = myIdsOnBoundary.begin();
+ for ( ; idListIt != myIdsOnBoundary.end(); idListIt++ )
+ {
+ list<list< int > >& groups = idListIt->second;
+ const TNodeSet& nodes = idListIt->first;
+ if ( nodes.size() != 2 )
+ continue; // not a link
+ const SMDS_MeshNode* n1 = *nodes.begin();
+ const SMDS_MeshNode* n2 = *nodes.rbegin();
+ TopoDS_Shape S1 = helper.GetSubShapeByNode( n1, aMeshDS );
+ TopoDS_Shape S2 = helper.GetSubShapeByNode( n2, aMeshDS );
+ if ( S1.IsNull() || S1.ShapeType() < TopAbs_EDGE ||
+ S2.IsNull() || S2.ShapeType() < TopAbs_EDGE )
+ continue;
+ TopoDS_Shape S;
+ if ( S1.ShapeType() == TopAbs_EDGE )
+ {
+ if ( S1 == S2 || helper.IsSubShape( S2, S1 ))
+ S = S1;
+ }
+ else if ( S2.ShapeType() == TopAbs_EDGE )
+ {
+ if ( helper.IsSubShape( S1, S2 ))
+ S = S2;
+ }
+ else
+ {
+ S = helper.GetCommonAncestor( S1, S2, *theMesh, TopAbs_EDGE );
+ }
+ if ( S.IsNull() )
+ continue;
+ const TopoDS_Edge & E = TopoDS::Edge( S );
+ helper.SetSubShape( E );
+ list<list< int > >::iterator g = groups.begin();
+ for ( ; g != groups.end(); ++g )
+ {
+ list< int >& ids = *g;
+ list< int >::iterator id = ids.begin();
+ for ( ; id != ids.end(); ++id )
+ if ( nodesVector[ *id ] && nodesVector[ *id ]->getshapeId() < 1 )
+ {
+ double u = 1e100;
+ aMeshDS->SetNodeOnEdge( nodesVector[ *id ], E, u );
+ helper.CheckNodeU( E, nodesVector[ *id ], u, 1e-7, true );
+ }
+ }
+ }
+ }
+ } // if ( onMeshElements )
+
else
{
nodesVector.resize( myPoints.size(), 0 );
- // to find point index
- map< TPoint*, int > pointIndex;
- for ( int i = 0; i < myPoints.size(); i++ )
- pointIndex.insert( make_pair( & myPoints[ i ], i ));
+ // find existing nodes on EDGEs and VERTEXes (IMP 22368)
+ map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
+ if ( !myShapeIDMap.IsEmpty() && aMeshDS->NbNodes() > 0 )
+
+ for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
+ {
+ const TopoDS_Shape& S = myShapeIDMap( idPointIt->first );
+ list< TPoint* > & points = idPointIt->second;
+ if ( points.empty() )
+ continue;
+
+ switch ( S.ShapeType() )
+ {
+ case TopAbs_VERTEX:
+ {
+ int pIndex = points.back() - &myPoints[0];
+ if ( !nodesVector[ pIndex ] )
+ nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
+ break;
+ }
+ case TopAbs_EDGE:
+ {
+ const TopoDS_Edge& edge = TopoDS::Edge( S );
+ map< double, const SMDS_MeshNode* > paramsOfNodes;
+ if ( !SMESH_Algo::GetSortedNodesOnEdge( aMeshDS, edge,
+ /*ignoreMediumNodes=*/false,
+ paramsOfNodes )
+ || paramsOfNodes.size() < 3 )
+ break;
+ // points on VERTEXes are included with wrong myU
+ list< TPoint* >::reverse_iterator pItR = ++points.rbegin();
+ list< TPoint* >::iterator pItF = ++points.begin();
+ const bool isForward = ( (*pItF)->myU < (*pItR)->myU );
+ map< double, const SMDS_MeshNode* >::iterator u2n = ++paramsOfNodes.begin();
+ map< double, const SMDS_MeshNode* >::iterator u2nEnd = --paramsOfNodes.end();
+ TPoint* p;
+ while ( u2n != u2nEnd && pItF != points.end() )
+ {
+ const double u = u2n->first;
+ const SMDS_MeshNode* n = u2n->second;
+ const double tol = ( (++u2n)->first - u ) / 20;
+ do
+ {
+ p = ( isForward ? *pItF : *pItR );
+ if ( Abs( u - p->myU ) < tol )
+ {
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = n;
+ ++pItF;
+ ++pItR;
+ break;
+ }
+ }
+ while ( p->myU < u && ( ++pItF, ++pItR != points.rend() ));
+ }
+ break;
+ }
+ default:;
+ }
+ } // end of "find existing nodes on EDGEs and VERTEXes"
// loop on sub-shapes of myShape: create nodes
- map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
+ idPointIt = myShapeIDToPointsMap.begin();
for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
{
TopoDS_Shape S;
- //SMESHDS_SubMesh * subMeshDS = 0;
if ( !myShapeIDMap.IsEmpty() ) {
S = myShapeIDMap( idPointIt->first );
- //subMeshDS = aMeshDS->MeshElements( S );
}
list< TPoint* > & points = idPointIt->second;
list< TPoint* >::iterator pIt = points.begin();
for ( ; pIt != points.end(); pIt++ )
{
TPoint* point = *pIt;
- int pIndex = pointIndex[ point ];
+ //int pIndex = pointIndex[ point ];
+ int pIndex = point - &myPoints[0];
if ( nodesVector [ pIndex ] )
continue;
SMDS_MeshNode* node = aMeshDS->AddNode (point->myXYZ.X(),
point->myXYZ.Z());
nodesVector [ pIndex ] = node;
- if ( true /*subMeshDS*/ ) {
+ if ( !S.IsNull() /*subMeshDS*/ ) {
// !!!!! do not merge new nodes with ones existing on submeshes (see method comment)
switch ( S.ShapeType() ) {
case TopAbs_VERTEX: {
createElements( theMesh, nodesVector, myElemPointIDs, myElements );
}
+ aMeshDS->compactMesh();
+
// const map<int,SMESHDS_SubMesh*>& sm = aMeshDS->SubMeshes();
// map<int,SMESHDS_SubMesh*>::const_iterator i_sm = sm.begin();
// for ( ; i_sm != sm.end(); i_sm++ )
const vector<const SMDS_MeshElement*>& theElements)
{
SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
- SMESH_MeshEditor editor( theMesh );
+ SMESH_MeshEditor editor( theMesh );
bool onMeshElements = !theElements.empty();
SMDS_ElemIteratorPtr noIt = elem->nodesIterator();
while ( noIt->more() ) {
SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>(smdsNode( noIt->next() ));
- if (!node->GetPosition()->GetShapeId() &&
- shellNodes.find( node ) == shellNodes.end() ) {
+ if ( node->getshapeId() < 1 &&
+ shellNodes.find( node ) == shellNodes.end() )
+ {
if ( S.ShapeType() == TopAbs_FACE )
- aMeshDS->SetNodeOnFace( node, shapeID );
+ aMeshDS->SetNodeOnFace( node, shapeID,
+ Precision::Infinite(),// <- it's a sign that UV is not set
+ Precision::Infinite());
else {
aMeshDS->SetNodeInVolume( node, shapeID );
shellNodes.insert( node );
if ( nbBoundaries > 2 )
{
// move boundaries in tmp list
- list< list< TPoint* > > tmpList;
+ list< list< TPoint* > > tmpList;
tmpList.splice( tmpList.begin(), boundaryList, boundaryList.begin(), boundaryList.end());
// make a map nb-key-points to boundary-position-in-tmpList,
// boundary-positions get ordered in it
boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos, ++outerBndPos );
} // if nbBoundaries > 1
-
+
// Check boundaries orientation and re-fill myKeyPointIDs
set< TPoint* > keyPointSet;
getShapePoints( shapeID ).push_back( point );
// detect key-points
if ( SMESH_Block::IsVertexID( shapeID ))
- myKeyPointIDs.push_back( i );
+ myKeyPointIDs.push_back( i );
}
}
myShapeIDMap.Clear();
myShape.Nullify();
myNbKeyPntInBoundary.clear();
+
+ myXYZ.clear();
+ myElemXYZIDs.clear();
+ myXYZIdToNodeMap.clear();
+ myElements.clear();
+ myOrderedNodes.clear();
+ myPolyElems.clear();
+ myPolyElemXYZIDs.clear();
+ myPolyhedronQuantities.clear();
+ myIdsOnBoundary.clear();
+ myReverseConnectivity.clear();
+}
+
+//================================================================================
+/*!
+ * \brief set ErrorCode and return true if it is Ok
+ */
+//================================================================================
+
+bool SMESH_Pattern::setErrorCode( const ErrorCode theErrorCode )
+{
+ myErrorCode = theErrorCode;
+ return myErrorCode == ERR_OK;
}
//=======================================================================
// check if a face is closed
int nbNodeOnSeamEdge = 0;
if ( myIs2D ) {
+ TopTools_MapOfShape seamVertices;
TopoDS_Face face = TopoDS::Face( theShape );
TopExp_Explorer eExp( theShape, TopAbs_EDGE );
- for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() )
- if ( BRep_Tool::IsClosed( TopoDS::Edge( eExp.Current() ), face ))
- nbNodeOnSeamEdge = 2;
+ for ( ; eExp.More() && nbNodeOnSeamEdge == 0; eExp.Next() ) {
+ const TopoDS_Edge& ee = TopoDS::Edge(eExp.Current());
+ if ( BRep_Tool::IsClosed(ee, face) ) {
+ // seam edge and vertices encounter twice in theFace
+ if ( !seamVertices.Add( TopExp::FirstVertex( ee ))) nbNodeOnSeamEdge++;
+ if ( !seamVertices.Add( TopExp::LastVertex( ee ))) nbNodeOnSeamEdge++;
+ }
+ }
}
-
+
// check nb of vertices
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap );
#ifdef _DEBUG_
vector< TPoint >::const_iterator pVecIt = myPoints.begin();
for ( int i = 0; pVecIt != myPoints.end(); pVecIt++, i++ )
- cout << i << ": " << *pVecIt;
+ MESSAGE_ADD ( std::endl << i << ": " << *pVecIt );
#endif
}
OS << " uv( " << xy.X() << " " << xy.Y() << " )";
u = p.myU;
OS << " u( " << u << " ))" << endl;
-
+
return OS;
}