-// 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
-//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// Copyright (C) 2007-2019 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
#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_MeshEditor.hxx"
+#include "SMESH_MesherHelper.hxx"
+#include "SMESH_subMesh.hxx"
+
+#include <BRepAdaptor_Curve.hxx>
#include <BRepTools.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <BRep_Tool.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 <TopLoc_Location.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.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_Utils.hxx>
#include "utilities.h"
using namespace std;
-typedef map< const SMDS_MeshElement*, int > TNodePointIDMap;
+typedef std::map< const SMDS_MeshElement*, int > TNodePointIDMap;
+typedef std::list< TopoDS_Edge > TWire;
-//=======================================================================
-//function : SMESH_Pattern
-//purpose :
-//=======================================================================
+#define smdsNode( elem ) static_cast<const SMDS_MeshNode*>( elem )
-SMESH_Pattern::SMESH_Pattern ()
+namespace
{
-}
+
//=======================================================================
//function : getInt
//purpose :
//=======================================================================
-static inline int getInt( const char * theSring )
+inline int getInt( const char * theSring )
{
if ( *theSring < '0' || *theSring > '9' )
return -1;
int val = strtol( theSring, &ptr, 10 );
if ( ptr == theSring ||
// there must not be neither '.' nor ',' nor 'E' ...
- (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
+ (*ptr != ' ' && *ptr != '\n' && *ptr != '\0' && *ptr != '\r'))
return -1;
return val;
//purpose :
//=======================================================================
-static inline double getDouble( const char * theSring )
+inline double getDouble( const char * theSring )
{
char *ptr;
return strtod( theSring, &ptr );
// Return the number of the found tokens
//=======================================================================
-static int readLine (list <const char*> & theFields,
- const char* & theLineBeg,
- const bool theClearFields )
+int readLine (list <const char*> & theFields,
+ const char* & theLineBeg,
+ const bool theClearFields )
{
if ( theClearFields )
theFields.clear();
return nbRead;
}
+//=======================================================================
+//function : isRealSeam
+//purpose : return true if an EDGE encounters twice in a FACE
+//=======================================================================
+
+// bool isRealSeam( const TopoDS_Edge& e, const TopoDS_Face& f )
+// {
+// if ( BRep_Tool::IsClosed( e, f ))
+// {
+// int nb = 0;
+// for (TopExp_Explorer exp( f, TopAbs_EDGE ); exp.More(); exp.Next())
+// if ( exp.Current().IsSame( e ))
+// if ( ++nb == 2 )
+// return true;
+// }
+// return false;
+// }
+
+//=======================================================================
+//function : loadVE
+//purpose : load VERTEXes and EDGEs in a map. Return nb loaded VERTEXes
+//=======================================================================
+
+int loadVE( const list< TopoDS_Edge > & eList,
+ TopTools_IndexedMapOfOrientedShape & map )
+{
+ list< TopoDS_Edge >::const_iterator eIt = eList.begin();
+ // vertices
+ int nbV;
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ {
+ nbV = map.Extent();
+ map.Add( TopExp::FirstVertex( *eIt, true ));
+ bool added = ( nbV < map.Extent() );
+ if ( !added ) { // vertex encountered twice
+ // a seam vertex have two corresponding key points
+ map.Add( TopExp::FirstVertex( *eIt, true ).Reversed());
+ }
+ }
+ nbV = map.Extent();
+
+ // edges
+ for ( eIt = eList.begin(); eIt != eList.end(); eIt++ )
+ map.Add( *eIt );
+
+ return nbV;
+}
+
+} // namespace
+
+//=======================================================================
+//function : SMESH_Pattern
+//purpose :
+//=======================================================================
+
+SMESH_Pattern::SMESH_Pattern (): myToKeepNodes(false)
+{
+}
+
//=======================================================================
//function : Load
//purpose : Load a pattern from <theFile>
bool SMESH_Pattern::Load (const char* theFileContents)
{
- MESSAGE("Load( file ) ");
-
+ Kernel_Utils::Localizer loc;
+
// file structure:
// ! This is a comment
// NB_POINTS ! 1 integer - the number of points in the pattern.
// X1 Y1 [Z1] ! 2 or 3 reals - nodes coordinates within 2D or 3D domain:
- // X2 Y2 [Z2] ! the pattern dimention is defined by the number of coordinates
+ // X2 Y2 [Z2] ! the pattern dimension is defined by the number of coordinates
// ...
// [ ID1 ID2 ... IDn ] ! Indices of key-points for a 2D pattern (only).
// ! elements description goes after all
// X1 Y1 [Z1] ! 2 or 3 reals - nodes coordinates within 2D or 3D domain:
- // read the first point coordinates to define pattern dimention
+ // read the first point coordinates to define pattern dimension
int dim = readLine( fields, lineBeg, clearFields );
if ( dim == 2 )
myIs2D = true;
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 );
}
}
}
-//=======================================================================
-//function : getOrderedEdges
-//purpose : return nb wires and a list of oredered edges
-//=======================================================================
-
-static int getOrderedEdges (const TopoDS_Face& theFace,
- const TopoDS_Vertex& theFirstVertex,
- list< TopoDS_Edge >& theEdges,
- list< int > & theNbVertexInWires)
-{
- // put wires in a list, so that an outer wire comes first
- list<TopoDS_Wire> aWireList;
- TopoDS_Wire anOuterWire = BRepTools::OuterWire( theFace );
- aWireList.push_back( anOuterWire );
- for ( TopoDS_Iterator wIt (theFace); wIt.More(); wIt.Next() )
- if ( !anOuterWire.IsSame( wIt.Value() ))
- aWireList.push_back( TopoDS::Wire( wIt.Value() ));
-
- // loop on edges of wires
- theNbVertexInWires.clear();
- list<TopoDS_Wire>::iterator wlIt = aWireList.begin();
- for ( ; wlIt != aWireList.end(); wlIt++ )
- {
- int iE;
- BRepTools_WireExplorer wExp( *wlIt, theFace );
- for ( iE = 0; wExp.More(); wExp.Next(), iE++ )
- {
- TopoDS_Edge edge = wExp.Current();
- edge = TopoDS::Edge( edge.Oriented( wExp.Orientation() ));
- theEdges.push_back( edge );
- }
- theNbVertexInWires.push_back( iE );
- iE = 0;
- if ( wlIt == aWireList.begin() && theEdges.size() > 1 ) { // the outer wire
- // orient closed edges
- list< TopoDS_Edge >::iterator eIt, eIt2;
- for ( eIt = theEdges.begin(); eIt != theEdges.end(); eIt++ )
- {
- TopoDS_Edge& edge = *eIt;
- if ( TopExp::FirstVertex( edge ).IsSame( TopExp::LastVertex( edge ) ))
- {
- eIt2 = eIt;
- bool isNext = ( eIt2 == theEdges.begin() );
- TopoDS_Edge edge2 = isNext ? *(++eIt2) : *(--eIt2);
- double f1,l1,f2,l2;
- Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( edge, theFace, f1,l1 );
- Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( edge2, theFace, f2,l2 );
- gp_Pnt2d pf = c1->Value( edge.Orientation() == TopAbs_FORWARD ? f1 : l1 );
- gp_Pnt2d pl = c1->Value( edge.Orientation() == TopAbs_FORWARD ? l1 : f1 );
- bool isFirst = ( edge2.Orientation() == TopAbs_FORWARD ? isNext : !isNext );
- gp_Pnt2d p2 = c2->Value( isFirst ? f2 : l2 );
- isFirst = ( p2.SquareDistance( pf ) < p2.SquareDistance( pl ));
- if ( isNext ? isFirst : !isFirst )
- edge.Reverse();
- }
- }
- // rotate theEdges until it begins from theFirstVertex
- if ( ! theFirstVertex.IsNull() )
- while ( !theFirstVertex.IsSame( TopExp::FirstVertex( theEdges.front(), true )))
- {
- theEdges.splice(theEdges.end(), theEdges,
- theEdges.begin(), ++ theEdges.begin());
- if ( iE++ > theNbVertexInWires.back() )
- break; // break infinite loop
- }
- }
- }
-
- return aWireList.size();
-}
-
//=======================================================================
//function : project
//purpose :
MESSAGE( "SMESH_Pattern: point projection FAILED");
return gp_XY(0.,0.);
}
- double u, v, minVal = DBL_MAX;
+ double u =0, v =0, minVal = DBL_MAX;
for ( int i = theProjectorPS.NbExt(); i > 0; i-- )
- if ( theProjectorPS.Value( i ) < minVal ) {
- minVal = theProjectorPS.Value( i );
+ if ( theProjectorPS.SquareDistance( i ) < minVal ) {
+ minVal = theProjectorPS.SquareDistance( i );
theProjectorPS.Point( i ).Parameter( u, v );
}
return gp_XY( u, v );
}
//=======================================================================
-//function : isMeshBoundToShape
-//purpose : return true if all 2d elements are bound to shape
+//function : areNodesBound
+//purpose : true if all nodes of faces are bound to shapes
//=======================================================================
-static bool isMeshBoundToShape(SMESH_Mesh* theMesh)
+template <class TFaceIterator> bool areNodesBound( TFaceIterator & faceItr )
{
- // check faces binding
- SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
- SMESHDS_SubMesh * aMainSubMesh = aMeshDS->MeshElements( aMeshDS->ShapeToMesh() );
- if ( aMeshDS->NbFaces() != aMainSubMesh->NbElements() )
- return false;
-
- // check face nodes binding
- SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
- while ( fIt->more() )
+ while ( faceItr->more() )
{
- SMDS_ElemIteratorPtr nIt = fIt->next()->nodesIterator();
+ SMDS_ElemIteratorPtr nIt = faceItr->next()->nodesIterator();
while ( nIt->more() )
{
- const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
- SMDS_PositionPtr pos = node->GetPosition();
- if ( !pos || !pos->GetShapeId() )
+ const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ if (node->getshapeId() <1) {
return false;
+ }
}
}
return true;
}
+//=======================================================================
+//function : isMeshBoundToShape
+//purpose : return true if all 2d elements are bound to shape
+// if aFaceSubmesh != NULL, then check faces bound to it
+// else check all faces in aMeshDS
+//=======================================================================
+
+static bool isMeshBoundToShape(SMESHDS_Mesh * aMeshDS,
+ SMESHDS_SubMesh * aFaceSubmesh,
+ const bool isMainShape)
+{
+ if ( isMainShape && aFaceSubmesh ) {
+ // check that all faces are bound to aFaceSubmesh
+ if ( aMeshDS->NbFaces() != aFaceSubmesh->NbElements() )
+ return false;
+ }
+
+ // check face nodes binding
+ if ( aFaceSubmesh ) {
+ SMDS_ElemIteratorPtr fIt = aFaceSubmesh->GetElements();
+ return areNodesBound( fIt );
+ }
+ SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
+ return areNodesBound( fIt );
+}
+
//=======================================================================
//function : Load
//purpose : Create a pattern from the mesh built on <theFace>.
bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
const TopoDS_Face& theFace,
- bool theProject)
+ bool theProject,
+ TopoDS_Vertex the1stVertex,
+ bool theKeepNodes)
{
- MESSAGE(" ::Load(face) " );
Clear();
myIs2D = true;
+ myToKeepNodes = theKeepNodes;
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 );
int nbNodes = ( !fSubMesh ? 0 : fSubMesh->NbNodes() );
int nbElems = ( !fSubMesh ? 0 : fSubMesh->NbElements() );
TopoDS_Face face = TopoDS::Face( theFace.Oriented( TopAbs_FORWARD ));
- // check that face is not closed
- TopoDS_Vertex bidon;
+ // check if face is closed
+ bool isClosed = helper.HasSeam();
list<TopoDS_Edge> eList;
- getOrderedEdges( face, bidon, eList, myNbKeyPntInBoundary );
- list<TopoDS_Edge>::iterator elIt = eList.begin();
- for ( ; elIt != eList.end() ; elIt++ )
- if ( BRep_Tool::IsClosed( *elIt , face ))
- return setErrorCode( ERR_LOADF_CLOSED_FACE );
-
+ list<TopoDS_Edge>::iterator elIt;
+ SMESH_Block::GetOrderedEdges( face, eList, myNbKeyPntInBoundary, the1stVertex );
+
+ // check that requested or needed projection is possible
+ bool isMainShape = theMesh->IsMainShape( face );
+ bool needProject = !isMeshBoundToShape( aMeshDS, fSubMesh, isMainShape );
+ bool canProject = ( nbElems ? true : isMainShape );
+ if ( isClosed )
+ canProject = false; // so far
+
+ if ( ( theProject || needProject ) && !canProject )
+ return setErrorCode( ERR_LOADF_CANT_PROJECT );
Extrema_GenExtPS projector;
GeomAdaptor_Surface aSurface( BRep_Tool::Surface( face ));
- if ( theProject || nbElems == 0 )
- projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
+ projector.Initialize( aSurface, 20,20, 1e-5,1e-5 );
int iPoint = 0;
TNodePointIDMap nodePointIDMap;
+ TNodePointIDMap closeNodePointIDMap; // for nodes on seam edges
- if ( nbElems == 0 || (theProject &&
- theMesh->IsMainShape( face ) &&
- !isMeshBoundToShape( theMesh )))
+ if ( needProject )
{
- MESSAGE("Project the whole mesh");
// ---------------------------------------------------------------
- // The case where the whole mesh is projected to theFace
+ // The case where the submesh is projected to theFace
// ---------------------------------------------------------------
- // put nodes of all faces in the nodePointIDMap and fill myElemPointIDs
- SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
+ // get all faces
+ SMDS_ElemIteratorPtr fIt;
+ if ( nbElems > 0 )
+ fIt = fSubMesh->GetElements();
+ else
+ fIt = aMeshDS->elementsIterator( SMDSAbs_Face );
+
+ // put nodes of all faces into the nodePointIDMap and fill myElemPointIDs
while ( fIt->more() )
{
+ const SMDS_MeshElement* face = fIt->next();
myElemPointIDs.push_back( TElemDef() );
TElemDef& elemPoints = myElemPointIDs.back();
- SMDS_ElemIteratorPtr nIt = fIt->next()->nodesIterator();
- while ( nIt->more() )
+ int nbNodes = face->NbCornerNodes();
+ for ( int i = 0;i < nbNodes; ++i )
{
- const SMDS_MeshElement* node = nIt->next();
- TNodePointIDMap::iterator nIdIt = nodePointIDMap.find( node );
- if ( nIdIt == nodePointIDMap.end() )
- {
- elemPoints.push_back( iPoint );
- nodePointIDMap.insert( make_pair( node, iPoint++ ));
- }
- else
- elemPoints.push_back( (*nIdIt).second );
+ const SMDS_MeshElement* node = face->GetNode( i );
+ TNodePointIDMap::iterator nIdIt = nodePointIDMap.insert( make_pair( node, -1 )).first;
+ if ( nIdIt->second == -1 )
+ nIdIt->second = iPoint++;
+ elemPoints.push_back( (*nIdIt).second );
}
}
myPoints.resize( iPoint );
TNodePointIDMap::iterator nIdIt = nodePointIDMap.begin();
for ( ; nIdIt != nodePointIDMap.end(); nIdIt++ )
{
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( (*nIdIt).first );
+ const SMDS_MeshNode* node = smdsNode( (*nIdIt).first );
TPoint * p = & myPoints[ (*nIdIt).second ];
p->myInitUV = project( node, projector );
p->myInitXYZ.SetCoord( p->myInitUV.X(), p->myInitUV.Y(), 0 );
const TopoDS_Vertex v = TopoDS::Vertex( vExp.Current() );
gp_Pnt2d uv = BRep_Tool::Parameters( v, face );
double minDist = DBL_MAX;
- int index;
+ int index = 0;
vector< TPoint >::const_iterator pVecIt = myPoints.begin();
for ( iPoint = 0; pVecIt != myPoints.end(); pVecIt++, iPoint++ ) {
double dist = uv.SquareDistance( (*pVecIt).myInitUV );
// Load shapes in the consequent order and count nb of points
- // vertices
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ ) {
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt );
- if ( eSubMesh )
- nbNodes += eSubMesh->NbNodes() + 1;
- }
- // edges
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
- // the face
+ loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
+ nbNodes += myShapeIDMap.Extent() - 1;
+
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
+ if ( SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( *elIt ))
+ nbNodes += eSubMesh->NbNodes() + 1;
+
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
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
+ Bnd_Box2d edgesUVBox;
+
+ list<int>::iterator nbEinW = myNbKeyPntInBoundary.begin();
+ int iE = 0;
+ vector< TopoDS_Edge > eVec;
+ for ( elIt = eList.begin(); elIt != eList.end(); elIt++, iE++ )
{
+ if ( isClosed && ( iE == 0 || iE == *nbEinW ))
+ {
+ // new wire begins; put wire EDGEs in eVec
+ list<TopoDS_Edge>::iterator eEnd = elIt;
+ if ( iE == *nbEinW )
+ ++nbEinW;
+ std::advance( eEnd, *nbEinW );
+ eVec.assign( elIt, eEnd );
+ iE = 0;
+ }
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
+ TopoDS_Shape v2 = TopExp::LastVertex( edge, true ); // always REVERSED
+ // to make adjacent edges share key-point, we make v2 FORWARD too
+ // (as we have different points for same shape with different orientation)
+ v2.Reverse();
+
+ // on closed face we must have REVERSED some of seam vertices
+ if ( isClosed ) {
+ if ( helper.IsSeamShape( edge ) ) {
+ if ( helper.IsRealSeam( edge ) && !isForward ) {
+ // reverse on reversed SEAM edge
+ v1.Reverse();
+ v2.Reverse();
+ }
+ }
+ else { // on CLOSED edge (i.e. having one vertex with different orientations)
+ for ( int is2 = 0; is2 < 2; ++is2 ) {
+ TopoDS_Shape & v = is2 ? v2 : v1;
+ if ( helper.IsRealSeam( v ) ) {
+ // reverse or not depending on orientation of adjacent seam
+ int iSeam = helper.WrapIndex( iE + ( is2 ? +1 : -1 ), eVec.size() );
+ if ( eVec[ iSeam ].Orientation() == TopAbs_REVERSED )
+ v.Reverse();
+ }
+ }
+ }
+ }
+
// the forward key-point
- TopoDS_Shape v = TopExp::FirstVertex( edge, true );
- list< TPoint* > & vPoint = getShapePoints( v );
- if ( vPoint.empty() )
+ list< TPoint* > * vPoint = & getShapePoints( v1 );
+ if ( vPoint->empty() )
{
- SMESHDS_SubMesh * vSubMesh = aMeshDS->MeshElements( v );
+ SMESHDS_SubMesh * vSubMesh = aMeshDS->MeshElements( v1 );
if ( vSubMesh && vSubMesh->NbNodes() ) {
myKeyPointIDs.push_back( iPoint );
SMDS_NodeIteratorPtr nIt = vSubMesh->GetNodes();
const SMDS_MeshNode* node = nIt->next();
- nodePointIDMap.insert( make_pair( node, iPoint ));
+ if ( v1.Orientation() == TopAbs_REVERSED )
+ closeNodePointIDMap.insert( make_pair( node, iPoint ));
+ else
+ nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* keyPoint = &myPoints[ iPoint++ ];
- vPoint.push_back( keyPoint );
+ vPoint->push_back( keyPoint );
if ( theProject )
keyPoint->myInitUV = project( node, projector );
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() )
- ePoints.push_back( vPoint.front() );
+ if ( !vPoint->empty() )
+ ePoints.push_back( vPoint->front() );
// on-edge points
SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( edge );
// 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 =
- static_cast<const SMDS_MeshNode*>( nIt->next() );
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && helper.IsMedium( node, SMDSAbs_Face )) {
+ ++nbMeduimNodes;
+ continue;
+ }
+ SMDS_EdgePositionPtr epos = node->GetPosition();
double u = epos->GetUParameter();
- paramNodeMap.insert( TParamNodeMap::value_type( u, node ));
+ paramNodeMap.insert( make_pair( u, node ));
}
+ if ((int) paramNodeMap.size() != eSubMesh->NbNodes() - nbMeduimNodes ) {
+ // 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 ((int) 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();
TPoint* p = & myPoints[ iPoint ];
ePoints.push_back( p );
const SMDS_MeshNode* node = isForward ? (*unIt).second : (*unRIt).second;
- nodePointIDMap.insert ( make_pair( node, iPoint ));
+ if ( isSeam && !isForward )
+ closeNodePointIDMap.insert( make_pair( node, iPoint ));
+ else
+ nodePointIDMap.insert ( make_pair( node, iPoint ));
if ( theProject )
p->myInitUV = project( node, projector );
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++;
}
}
// the reverse key-point
- v = TopExp::LastVertex( edge, true ).Reversed();
- list< TPoint* > & vPoint2 = getShapePoints( v );
- if ( vPoint2.empty() )
+ vPoint = & getShapePoints( v2 );
+ if ( vPoint->empty() )
{
- SMESHDS_SubMesh * vSubMesh = aMeshDS->MeshElements( v );
+ SMESHDS_SubMesh * vSubMesh = aMeshDS->MeshElements( v2 );
if ( vSubMesh && vSubMesh->NbNodes() ) {
myKeyPointIDs.push_back( iPoint );
SMDS_NodeIteratorPtr nIt = vSubMesh->GetNodes();
const SMDS_MeshNode* node = nIt->next();
- nodePointIDMap.insert( make_pair( node, iPoint ));
+ if ( v2.Orientation() == TopAbs_REVERSED )
+ closeNodePointIDMap.insert( make_pair( node, iPoint ));
+ else
+ nodePointIDMap.insert( make_pair( node, iPoint ));
TPoint* keyPoint = &myPoints[ iPoint++ ];
- vPoint2.push_back( keyPoint );
+ vPoint->push_back( keyPoint );
if ( theProject )
keyPoint->myInitUV = project( node, projector );
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 ( !vPoint2.empty() )
- ePoints.push_back( vPoint2.front() );
+ if ( !vPoint->empty() )
+ ePoints.push_back( vPoint->front() );
// compute U of edge-points
if ( theProject )
SMDS_NodeIteratorPtr nIt = fSubMesh->GetNodes();
while ( nIt->more() )
{
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( 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 );
- if ( theProject )
+ if ( theProject || edgesUVBox.IsOut( p->myInitUV ) )
p->myInitUV = project( node, projector );
else {
- const SMDS_FacePosition* pos =
- static_cast<const SMDS_FacePosition*>(node->GetPosition().get());
+ SMDS_FacePositionPtr pos = 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() ) {
- SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator();
+ while ( elemIt->more() )
+ {
+ const SMDS_MeshElement* elem = elemIt->next();
+ SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
myElemPointIDs.push_back( TElemDef() );
TElemDef& elemPoints = myElemPointIDs.back();
+ // find point indices corresponding to element nodes
while ( nIt->more() )
- elemPoints.push_back( nodePointIDMap[ nIt->next() ]);
+ {
+ const SMDS_MeshNode* node = smdsNode( nIt->next() );
+ 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
+ if ( helper.IsRealSeam( node->getshapeId() ) &&
+ ( n_id = closeNodePointIDMap.find( node )) != not_found )
+ {
+ TPoint & p1 = myPoints[ iPoint ];
+ TPoint & p2 = myPoints[ n_id->second ];
+ // Select point closest to the rest nodes of element in UV space
+ SMDS_ElemIteratorPtr nIt2 = elem->nodesIterator();
+ const SMDS_MeshNode* notSeamNode = 0;
+ // find node not on a seam edge
+ while ( nIt2->more() && !notSeamNode ) {
+ const SMDS_MeshNode* n = smdsNode( nIt2->next() );
+ if ( !helper.IsSeamShape( n->getshapeId() ))
+ notSeamNode = n;
+ }
+ gp_Pnt2d uv = helper.GetNodeUV( theFace, node, notSeamNode );
+ double dist1 = uv.SquareDistance( p1.myInitUV );
+ double dist2 = uv.SquareDistance( p2.myInitUV );
+ if ( dist2 < dist1 )
+ iPoint = n_id->second;
+ }
+ elemPoints.push_back( iPoint );
+ }
}
}
+ myPoints.resize( nodePointIDMap.size() + closeNodePointIDMap.size() );
myIsBoundaryPointsFound = true;
}
+ if ( myToKeepNodes )
+ {
+ myInNodes.resize( nodePointIDMap.size() + closeNodePointIDMap.size() );
+
+ TNodePointIDMap::iterator nIdIt = nodePointIDMap.begin();
+ for ( ; nIdIt != nodePointIDMap.end(); nIdIt++ )
+ myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first );
+
+ nIdIt = closeNodePointIDMap.begin();
+ for ( ; nIdIt != closeNodePointIDMap.end(); nIdIt++ )
+ myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first );
+ }
+
// Assure that U range is proportional to V range
Bnd_Box2d bndBox;
double dU = maxU - minU, dV = maxV - minV;
if ( dU <= DBL_MIN || dV <= DBL_MIN ) {
Clear();
- return setErrorCode( ERR_LOADF_NARROW_FACE );
+ bndBox.SetVoid();
+ // define where is the problem, in the face or in the mesh
+ TopExp_Explorer vExp( face, TopAbs_VERTEX );
+ for ( ; vExp.More(); vExp.Next() ) {
+ gp_Pnt2d uv = BRep_Tool::Parameters( TopoDS::Vertex( vExp.Current() ), face );
+ bndBox.Add( uv );
+ }
+ bndBox.Get( minU, minV, maxU, maxV );
+ dU = maxU - minU, dV = maxV - minV;
+ if ( dU <= DBL_MIN || dV <= DBL_MIN )
+ // face problem
+ return setErrorCode( ERR_LOADF_NARROW_FACE );
+ else
+ // mesh is projected onto a line, e.g.
+ return setErrorCode( ERR_LOADF_CANT_PROJECT );
}
double ratio = dU / dV, maxratio = 3, scale;
int iCoord = 0;
BRep_Tool::CurveOnSurface( theEdge, TopoDS::Face( myShape ), f, l );
ePoints.back()->myInitU = 1.0;
+ //ePoints.front()->myInitU = 0.0; //myUV = C2d->Value( isForward ? f : l ).XY();
list< TPoint* >::const_iterator pIt = ePoints.begin();
for ( pIt++; pIt != ePoints.end(); pIt++ )
{
gp_XY loc1 = uv11 * ( 1 - r1 ) + uv12 * r1;
gp_XY loc2 = uv21 * ( 1 - r2 ) + uv22 * r2;
resUV = 0.5 * ( loc1 + loc2 );
- isDeformed = ( loc1 - loc2 ).SquareModulus() > 1e-8;
+ //isDeformed = ( loc1 - loc2 ).SquareModulus() > 1e-8;
+ // SKL 26.07.2007 for NPAL16567
+ double d1 = (uv11-uv12).Modulus();
+ double d2 = (uv21-uv22).Modulus();
+ // double delta = d1*d2*1e-6; PAL17233
+ double delta = min( d1, d2 ) / 10.;
+ isDeformed = ( loc1 - loc2 ).SquareModulus() > delta * delta;
+
// double len1 = ( uv11 - uv12 ).Modulus();
// double len2 = ( uv21 - uv22 ).Modulus();
// 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 ) {
+ // MESSAGE("intersectIsolines(), d1 = " << d1 << ", d2 = " << d2 << ", delta = " << delta <<
+ // ", " << (loc1 - loc2).SquareModulus() << " > " << delta * delta);
+ // }
return true;
}
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++ )
{
}
if ( !intersectIsolines( uv1[0], uv2[0], ratio[0],
uv1[1], uv2[1], ratio[1], theUV, theIsDeformed )) {
- MESSAGE(" Cant intersect isolines for a point "<<theInitUV.X()<<", "<<theInitUV.Y());
+ MESSAGE(" Can't intersect isolines for a point "<<theInitUV.X()<<", "<<theInitUV.Y());
return setErrorCode( ERR_APPLF_BAD_TOPOLOGY );
}
TIsoNode* myNext[4]; // order: (iDir=0,isForward=0), (1,0), (0,1), (1,1)
TIsoNode* myBndNodes[4]; // order: (iDir=0,i=0), (1,0), (0,1), (1,1)
TIsoNode(double initU, double initV):
- myInitUV( initU, initV ), myUV( 1e100, 1e100 ), myIsMovable(true)
+ myIsMovable(true), myInitUV( initU, initV ), myUV( 1e100, 1e100 )
{ myNext[0] = myNext[1] = myNext[2] = myNext[3] = 0; }
bool IsUVComputed() const
{ return myUV.X() != 1e100; }
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;
return false;
}
else {
- //MESSAGE(" Cant improve UV, uv: "<<uv.X()<<" "<<uv.Y());
+ //MESSAGE(" Can't improve UV, uv: "<<uv.X()<<" "<<uv.Y());
}
}
if ( !oldIsIn && nbOldFix ) {
return false;
}
else {
- //MESSAGE(" Cant fix UV, uv: "<<uv.X()<<" "<<uv.Y());
+ //MESSAGE(" Can't fix UV, uv: "<<uv.X()<<" "<<uv.Y());
}
}
if ( newIsIn && oldIsIn )
compUVByElasticIsolines(const list< list< TPoint* > >& theBndPoints,
const list< TPoint* >& thePntToCompute)
{
+ return false; // PAL17233
//cout << "============================== KEY POINTS =============================="<<endl;
// list< int >::iterator kpIt = myKeyPointIDs.begin();
// for ( ; kpIt != myKeyPointIDs.end(); kpIt++ ) {
// " dir0: "<<bndNode2->myDir[0].X()<<" "<<bndNode2->myDir[0].Y() <<
// " dir1: "<<bndNode2->myDir[1].X()<<" "<<bndNode2->myDir[1].Y() << endl;
}
+ else {
+ /// WHAT IN THIS CASE ????????????? MAY BE THIS, I AM NOT SURE :(
+ node->SetBoundaryNode( 0, iDir, 0 );
+ node->SetBoundaryNode( 0, iDir, 1 );
+ }
}
nIt++; nPrevIt++;
if ( nNextIt != isoLine.end() ) nNextIt++;
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;
list < TIsoNode* > internNodes;
bool needIteration = true;
if ( startNodes.empty() ) {
- MESSAGE( " Starting UV by compUVByIsoIntersection()");
+ //MESSAGE( " Starting UV by compUVByIsoIntersection()");
needIteration = false;
map < double, TIsoLine >& isos = isoMap[ 0 ];
map < double, TIsoLine >::iterator isoIt = isos.begin();
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 );
// dir = node->myDir[ 1 - iDir ].XY() * ( isEnd ? -1. : 1. );
//cout << "__________"<<endl<< "NODE: "<<node->myInitUV.X()<<" "<<node->myInitUV.Y()<<endl;
TIsoNode* bndNode = node->GetBoundaryNode( iDir, isEnd );
+ if ( !bndNode ) {
+ MESSAGE("Why we are here?");
+ continue;
+ }
gp_XY tgt( bndNode->myDir[0].XY() + bndNode->myDir[1].XY() );
dir.SetCoord( 1, tgt.Y() * ( reversed ? 1 : -1 ));
dir.SetCoord( 2, tgt.X() * ( reversed ? -1 : 1 ));
newUV += prevNode1->myUV + dir * step[ iDir ];
}
sumDir += dir;
- prevN[ iDir ] = prevNode1;
nbComp++;
}
}
+ if ( !nbComp ) continue;
newUV /= nbComp;
node->myUV = newUV;
//cout << "NODE: "<<node->myInitUV.X()<<" "<<node->myInitUV.Y()<<endl;
}
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 {
// line[ iDir ].SetDirection( node->myDir[ iDir ] );
}
// define ratio
- double locR[2] = { 0, 0 };
+ bool ok = true; // <- stupid fix TO AVOID PB OF NODES WITH NULL BND NODES
+// double locR[2] = { 0, 0 };
for ( iDir = 0; iDir < 2; iDir++ )
{
const int iCoord = 2 - iDir; // coord changing along an isoline
TIsoNode* bndNode1 = node->GetBoundaryNode( iDir, 0 );
TIsoNode* bndNode2 = node->GetBoundaryNode( iDir, 1 );
+ if ( !bndNode1 || !bndNode2 ) {
+ ok = false; break;
+ }
double par1 = bndNode1->myInitUV.Coord( iCoord );
double par2 = node->myInitUV.Coord( iCoord );
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
//IntAna2d_AnaIntersection inter( line[0], line[1] );
- if ( /*inter.IsDone() && inter.NbPoints() ==*/ 1 )
+ if ( ok /*inter.IsDone() && inter.NbPoints() ==*/ )
{
// double intR = 1 - locR[0] - locR[1];
// gp_XY newUV = inter.Point(1).Value().XY();
#endif
} while ( maxMove > 1e-8 && nbIter++ < maxNbIter );
- MESSAGE( "compUVByElasticIsolines(): Nb iterations " << nbIter << " dist: " << sqrt( maxMove ));
+ //MESSAGE( "compUVByElasticIsolines(): Nb iterations " << nbIter << " dist: " << sqrt( maxMove ));
if ( nbIter >= maxNbIter && sqrt(maxMove) > minUvSize * 0.05 ) {
MESSAGE( "compUVByElasticIsolines() failed: "<<sqrt(maxMove)<<">"<<minUvSize * 0.05);
}
}
}
-
-
+
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;
list< TPoint* > & ePoints = getShapePoints( eID++ );
TPoint* p = ePoints.front();
if ( !compUVByIsoIntersection( theEdgesPointsList, p->myInitUV, p->myUV, aBool )) {
- MESSAGE("cant sortSameSizeWires()");
+ MESSAGE("can't sortSameSizeWires()");
return false;
}
gcVec[iW] += p->myUV;
// " \t vertex: " << vGcVec[iW].X() << " " << vGcVec[iW].Y() << endl;
double minDist = DBL_MAX;
gp_XY & wGc = vGcVec[ iW ];
- int bIndex;
+ int bIndex = 0;
for ( int iB = 0; iB < nbWires; iB++ ) {
if ( bndFound[ iB ] ) continue;
double dist = ( wGc - gcVec[ iB ] ).SquareModulus();
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();
const TopoDS_Vertex& theVertexOnKeyPoint1,
const bool theReverse)
{
- MESSAGE(" ::Apply(face) " );
TopoDS_Face face = theReverse ? TopoDS::Face( theFace.Reversed() ) : theFace;
if ( !setShapeToMesh( face ))
return false;
list< TopoDS_Edge > eList;
list< int > nbVertexInWires;
- int nbWires = 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 ");
}
// here shapes get IDs, for the outer wire IDs are OK
- 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 ));
- }
- int nbVertices = myShapeIDMap.Extent();
-
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
-
+ int nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
- if ( myShapeIDToPointsMap.size() != myShapeIDMap.Extent()/* + nbSeamShapes*/ ) {
+ if ((int) myShapeIDToPointsMap.size() != myShapeIDMap.Extent() ) {
MESSAGE( myShapeIDToPointsMap.size() <<" != " << myShapeIDMap.Extent());
return setErrorCode( ERR_APPLF_INTERNAL_EEROR );
}
list< list< TPoint* > > edgesPointsList;
edgesPointsList.push_back( list< TPoint* >() );
list< TPoint* > * edgesPoints = & edgesPointsList.back();
- list< TPoint* >::iterator pIt;
+ list< TPoint* >::iterator pIt, pEnd;
// compute UV of points on the outer wire
int iE, nbEdgesInOuterWire = nbVertexInWires.front();
+ list< TopoDS_Edge >::iterator elIt;
for (iE = 0, elIt = eList.begin();
iE < nbEdgesInOuterWire && elIt != eList.end();
iE++, elIt++ )
// If there are several wires, define the order of edges of inner wires:
// compute UV of inner edge-points using 2 methods: the one for in-face points
// and the one for on-edge points and then choose the best edge order
- // by the best correspondance of the 2 results
+ // by the best correspondence of the 2 results.
+ // The wires are sorted by number of edges to correspond to wires of the pattern
if ( nbWires > 1 )
{
// compute UV of inner edge-points using the method for in-face points
- // and devide eList into a list of separate wires
+ // and divide eList into a list of separate wires
bool aBool;
- list< list< TopoDS_Edge > > wireList;
+ list< TWire > wireList;
list<TopoDS_Edge>::iterator eIt = elIt;
list<int>::iterator nbEIt = nbVertexInWires.begin();
for ( nbEIt++; nbEIt != nbVertexInWires.end(); nbEIt++ )
{
int nbEdges = *nbEIt;
wireList.push_back( list< TopoDS_Edge >() );
- list< TopoDS_Edge > & wire = wireList.back();
+ TWire & wire = wireList.back();
for ( iE = 0 ; iE < nbEdges; eIt++, iE++ )
{
list< TPoint* > & ePoints = getShapePoints( *eIt );
for ( pIt++; pIt != ePoints.end(); pIt++ ) {
TPoint* p = (*pIt);
if ( !compUVByIsoIntersection( edgesPointsList, p->myInitUV, p->myUV, aBool )) {
- MESSAGE("cant Apply(face)");
+ MESSAGE("can't Apply(face)");
return false;
}
// keep the computed UV to compare against by setFirstEdge()
// find points - edge correspondence for wires of unique size,
// edge order within a wire should be defined only
- list< list< TopoDS_Edge > >::iterator wlIt = wireList.begin();
+ list< TWire >::iterator wlIt = wireList.begin();
while ( wlIt != wireList.end() )
{
- list< TopoDS_Edge >& wire = (*wlIt);
- int nbEdges = wire.size();
+ TWire& wire = (*wlIt);
+ size_t nbEdges = wire.size();
wlIt++;
if ( wlIt == wireList.end() || (*wlIt).size() != nbEdges ) // a unique size wire
{
edgesPoints->insert( edgesPoints->end(), ePoints.begin(), (--ePoints.end()));
}
}
+ else
+ {
+ // skip same size wires
+ while ( wlIt != wireList.end() && (*wlIt).size() == nbEdges )
+ wlIt++;
+ }
id1 += nbEdges;
}
// find boundary - wire correspondence for several wires of same size
-
+
id1 = nbVertices + nbEdgesInOuterWire + 1;
wlIt = wireList.begin();
while ( wlIt != wireList.end() )
{
- int nbSameSize = 0, nbEdges = (*wlIt).size();
- list< list< TopoDS_Edge > >::iterator wlIt2 = wlIt;
+ size_t nbSameSize = 0, nbEdges = (*wlIt).size();
+ list< TWire >::iterator wlIt2 = wlIt;
wlIt2++;
while ( wlIt2 != wireList.end() && (*wlIt2).size() == nbEdges ) { // a same size wire
nbSameSize++;
}
// add well-ordered edges to eList
-
+
for ( wlIt = wireList.begin(); wlIt != wireList.end(); wlIt++ )
{
- list< TopoDS_Edge >& wire = (*wlIt);
+ TWire& wire = (*wlIt);
eList.splice( eList.end(), wire, wire.begin(), wire.end() );
}
// re-fill myShapeIDMap - all shapes get good IDs
myShapeIDMap.Clear();
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( TopExp::FirstVertex( *elIt, true ));
- for ( elIt = eList.begin(); elIt != eList.end(); elIt++ )
- myShapeIDMap.Add( *elIt );
+ nbVertices = loadVE( eList, myShapeIDMap );
myShapeIDMap.Add( face );
-
+
} // there are inner wires
+ // Set XYZ of on-vertex points
+
+ // for ( int iV = 1; iV <= nbVertices; ++iV )
+ // {
+ // const TopoDS_Vertex& V = TopoDS::Vertex( myShapeIDMap( iV ));
+ // list< TPoint* > & vPoints = getShapePoints( iV );
+ // if ( !vPoints.empty() )
+ // {
+ // //vPoints.front()->myUV = BRep_Tool::Parameters( V, theFace ).XY();
+ // vPoints.front()->myXYZ = BRep_Tool::Pnt( V );
+ // }
+ // }
+
// Compute XYZ of on-edge points
TopLoc_Location loc;
for ( iE = nbVertices + 1, elIt = eList.begin(); elIt != eList.end(); elIt++ )
{
- double f,l;
- Handle(Geom_Curve) C3d = BRep_Tool::Curve( *elIt, loc, f, l );
- const gp_Trsf & aTrsf = loc.Transformation();
+ BRepAdaptor_Curve C3d( *elIt );
list< TPoint* > & ePoints = getShapePoints( iE++ );
- pIt = ePoints.begin();
- for ( pIt++; pIt != ePoints.end(); pIt++ )
+ for ( pIt = ++ePoints.begin(), pEnd = ePoints.end(); pIt != pEnd; pIt++ )
{
TPoint* point = *pIt;
- point->myXYZ = C3d->Value( point->myU );
- if ( !loc.IsIdentity() )
- aTrsf.Transforms( point->myXYZ.ChangeCoord() );
+ point->myXYZ = C3d.Value( point->myU );
}
}
for ( pIt = fPoints.begin(); !isDeformed && pIt != fPoints.end(); pIt++ )
if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
(*pIt)->myUV, isDeformed )) {
- MESSAGE("cant Apply(face)");
+ MESSAGE("can't Apply(face)");
return false;
}
// try to use a complex algo if it is a difficult case
for ( ; pIt != fPoints.end(); pIt++ ) // continue with the simple algo
if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
(*pIt)->myUV, isDeformed )) {
- MESSAGE("cant Apply(face)");
+ MESSAGE("can't Apply(face)");
return false;
}
}
}
// 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 = static_cast<const SMDS_MeshNode*>( 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();
for ( pIt = fPoints.begin(); !isDeformed && pIt != fPoints.end(); pIt++ )
if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
(*pIt)->myUV, isDeformed )) {
- MESSAGE("cant Apply(face)");
+ MESSAGE("can't Apply(face)");
return false;
}
// try to use a complex algo if it is a difficult case
for ( ; pIt != fPoints.end(); pIt++ ) // continue with the simple algo
if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
(*pIt)->myUV, isDeformed )) {
- MESSAGE("cant Apply(face)");
+ MESSAGE("can't Apply(face)");
return false;
}
}
return setErrorCode( ERR_OK );
}
+//=======================================================================
+//function : Apply
+//purpose : Compute nodes coordinates applying
+// the loaded pattern to <theFace>. The first key-point
+// will be mapped into <theNodeIndexOnKeyPoint1>-th node
+//=======================================================================
+
+bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh,
+ const SMDS_MeshFace* theFace,
+ const TopoDS_Shape& theSurface,
+ const int theNodeIndexOnKeyPoint1,
+ const bool theReverse)
+{
+// MESSAGE(" ::Apply(MeshFace) " );
+ if ( theSurface.IsNull() || theSurface.ShapeType() != TopAbs_FACE ) {
+ return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse);
+ }
+ const TopoDS_Face& face = TopoDS::Face( theSurface );
+ TopLoc_Location loc;
+ Handle(Geom_Surface) surface = BRep_Tool::Surface( face, loc );
+ const gp_Trsf & aTrsf = loc.Transformation();
+
+ if ( !IsLoaded() ) {
+ MESSAGE( "Pattern not loaded" );
+ return setErrorCode( ERR_APPL_NOT_LOADED );
+ }
+
+ // check nb of nodes
+ if (theFace->NbNodes() != myNbKeyPntInBoundary.front() ) {
+ MESSAGE( myKeyPointIDs.size() << " != " << theFace->NbNodes() );
+ return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
+ }
+
+ // find points on edges, it fills myNbKeyPntInBoundary
+ if ( !findBoundaryPoints() )
+ return false;
+
+ // check that there are no holes in a pattern
+ if (myNbKeyPntInBoundary.size() > 1 ) {
+ return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
+ }
+
+ // Define the nodes order
+
+ list< const SMDS_MeshNode* > nodes;
+ list< const SMDS_MeshNode* >::iterator n = nodes.end();
+ SMDS_ElemIteratorPtr noIt = theFace->nodesIterator();
+ int iSub = 0;
+ while ( noIt->more() ) {
+ const SMDS_MeshNode* node = smdsNode( noIt->next() );
+ nodes.push_back( node );
+ if ( iSub++ == theNodeIndexOnKeyPoint1 )
+ n = --nodes.end();
+ }
+ if ( n != nodes.end() ) {
+ if ( theReverse ) {
+ if ( n != --nodes.end() )
+ nodes.splice( nodes.begin(), nodes, ++n, nodes.end() );
+ nodes.reverse();
+ }
+ else if ( n != nodes.begin() )
+ nodes.splice( nodes.end(), nodes, nodes.begin(), n );
+ }
+
+ // find a node not on a seam edge, if necessary
+ SMESH_MesherHelper helper( *theMesh );
+ helper.SetSubShape( theSurface );
+ const SMDS_MeshNode* inFaceNode = 0;
+ if ( helper.GetNodeUVneedInFaceNode() )
+ {
+ SMESH_MeshEditor editor( theMesh );
+ for ( n = nodes.begin(); ( !inFaceNode && n != nodes.end()); ++n ) {
+ int shapeID = editor.FindShape( *n );
+ if ( !shapeID )
+ return Apply( theFace, theNodeIndexOnKeyPoint1, theReverse);
+ if ( !helper.IsSeamShape( shapeID ))
+ inFaceNode = *n;
+ }
+ }
+
+ // Set UV of key-points (i.e. of nodes of theFace )
+ vector< gp_XY > keyUV( theFace->NbNodes() );
+ myOrderedNodes.resize( theFace->NbNodes() );
+ for ( iSub = 1, n = nodes.begin(); n != nodes.end(); ++n, ++iSub )
+ {
+ TPoint* p = getShapePoints( iSub ).front();
+ p->myUV = helper.GetNodeUV( face, *n, inFaceNode );
+ p->myXYZ = gp_XYZ( (*n)->X(), (*n)->Y(), (*n)->Z() );
+
+ keyUV[ iSub-1 ] = p->myUV;
+ myOrderedNodes[ iSub-1 ] = *n;
+ }
+
+ // points on edges to be used for UV computation of in-face points
+ list< list< TPoint* > > edgesPointsList;
+ edgesPointsList.push_back( list< TPoint* >() );
+ list< TPoint* > * edgesPoints = & edgesPointsList.back();
+ list< TPoint* >::iterator pIt;
+
+ // compute UV and XYZ of points on edges
+
+ for ( size_t i = 0; i < myOrderedNodes.size(); ++i, ++iSub )
+ {
+ gp_XY& uv1 = keyUV[ i ];
+ gp_XY& uv2 = ( i+1 < keyUV.size() ) ? keyUV[ i+1 ] : keyUV[ 0 ];
+
+ list< TPoint* > & ePoints = getShapePoints( iSub );
+ ePoints.back()->myInitU = 1.0;
+ list< TPoint* >::const_iterator pIt = ++ePoints.begin();
+ while ( *pIt != ePoints.back() )
+ {
+ TPoint* p = *pIt++;
+ p->myUV = uv1 * ( 1 - p->myInitU ) + uv2 * p->myInitU;
+ p->myXYZ = surface->Value( p->myUV.X(), p->myUV.Y() );
+ if ( !loc.IsIdentity() )
+ aTrsf.Transforms( p->myXYZ.ChangeCoord() );
+ }
+ // collect on-edge points (excluding the last one)
+ edgesPoints->insert( edgesPoints->end(), ePoints.begin(), --ePoints.end());
+ }
+
+ // Compute UV and XYZ of in-face points
+
+ // try to use a simple algo to compute UV
+ list< TPoint* > & fPoints = getShapePoints( iSub );
+ bool isDeformed = false;
+ for ( pIt = fPoints.begin(); !isDeformed && pIt != fPoints.end(); pIt++ )
+ if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
+ (*pIt)->myUV, isDeformed )) {
+ MESSAGE("can't Apply(face)");
+ return false;
+ }
+ // try to use a complex algo if it is a difficult case
+ if ( isDeformed && !compUVByElasticIsolines( edgesPointsList, fPoints ))
+ {
+ for ( ; pIt != fPoints.end(); pIt++ ) // continue with the simple algo
+ if ( !compUVByIsoIntersection( edgesPointsList, (*pIt)->myInitUV,
+ (*pIt)->myUV, isDeformed )) {
+ MESSAGE("can't Apply(face)");
+ return false;
+ }
+ }
+
+ for ( pIt = fPoints.begin(); pIt != fPoints.end(); pIt++ )
+ {
+ TPoint * point = *pIt;
+ point->myXYZ = surface->Value( point->myUV.X(), point->myUV.Y() );
+ if ( !loc.IsIdentity() )
+ aTrsf.Transforms( point->myXYZ.ChangeCoord() );
+ }
+
+ myIsComputed = true;
+
+ return setErrorCode( ERR_OK );
+}
+
//=======================================================================
//function : undefinedXYZ
//purpose :
// will be mapped into <theNodeIndexOnKeyPoint1>-th node
//=======================================================================
-bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& theFaces,
+bool SMESH_Pattern::Apply (SMESH_Mesh* theMesh,
+ std::set<const SMDS_MeshFace*>& theFaces,
const int theNodeIndexOnKeyPoint1,
const bool theReverse)
{
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 );
+
// apply to each face in theFaces set
set<const SMDS_MeshFace*>::iterator face = theFaces.begin();
for ( ; face != theFaces.end(); ++face )
{
- if ( !Apply( *face, theNodeIndexOnKeyPoint1, theReverse )) {
+// int curShapeId = editor.FindShape( *face );
+// if ( curShapeId != shapeID ) {
+// if ( curShapeId )
+// shape = theMesh->GetMeshDS()->IndexToShape( curShapeId );
+// else
+// shape.Nullify();
+// shapeID = curShapeId;
+// }
+ bool ok;
+ if ( shape.IsNull() )
+ ok = Apply( *face, theNodeIndexOnKeyPoint1, theReverse );
+ else
+ ok = Apply( theMesh, *face, shape, theNodeIndexOnKeyPoint1, theReverse );
+ if ( !ok ) {
MESSAGE( "Failed on " << *face );
continue;
}
}
// 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();
}
const int theNode000Index,
const int theNode001Index)
{
- MESSAGE(" ::Apply(set<MeshVolumes>) " );
-
if ( !IsLoaded() ) {
MESSAGE( "Pattern not loaded" );
return setErrorCode( ERR_APPL_NOT_LOADED );
// to find point index
map< TPoint*, int > pointIndex;
- for ( int i = 0; i < myPoints.size(); i++ )
+ for ( size_t i = 0; i < myPoints.size(); i++ )
pointIndex.insert( make_pair( & myPoints[ i ], i ));
int ind1 = 0; // lowest point index for an element
//=======================================================================
bool SMESH_Pattern::Load (SMESH_Mesh* theMesh,
- const TopoDS_Shell& theBlock)
+ const TopoDS_Shell& theBlock,
+ bool theKeepNodes)
{
- MESSAGE(" ::Load(volume) " );
Clear();
myIs2D = false;
- SMESHDS_Mesh * aMeshDS = theMesh->GetMeshDS();
+ myToKeepNodes = theKeepNodes;
+ SMESHDS_SubMesh * aSubMesh;
+
+ const bool isQuadMesh = theMesh->NbVolumes( ORDER_QUADRATIC );
// load shapes in myShapeIDMap
SMESH_Block block;
for ( shapeID = 1; shapeID <= myShapeIDMap.Extent(); shapeID++ )
{
const TopoDS_Shape& S = myShapeIDMap( shapeID );
- SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( S );
+ aSubMesh = getSubmeshWithElements( theMesh, S );
if ( aSubMesh )
nbNodes += aSubMesh->NbNodes();
}
{
const TopoDS_Shape& S = myShapeIDMap( shapeID );
list< TPoint* > & shapePoints = getShapePoints( shapeID );
- SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( S );
+ aSubMesh = getSubmeshWithElements( theMesh, S );
if ( ! aSubMesh ) continue;
SMDS_NodeIteratorPtr nIt = aSubMesh->GetNodes();
if ( !nIt->more() ) continue;
- // store a node and a point
+ // store a node and a point
while ( nIt->more() ) {
- const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ 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 =
- static_cast<const SMDS_MeshNode*>( nIt->next() );
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ const SMDS_MeshNode* node = nIt->next();
+ if ( isQuadMesh && SMESH_MeshEditor::IsMedium( node, SMDSAbs_Edge ))
+ continue;
+ SMDS_EdgePositionPtr epos = node->GetPosition();
double u = ( epos->GetUParameter() - f ) / ( l - f );
(*pIt)->myInitXYZ.SetCoord( iCoord, isForward ? u : 1 - u );
}
// load elements
- SMESHDS_SubMesh * aSubMesh = aMeshDS->MeshElements( theBlock );
+ aSubMesh = getSubmeshWithElements( theMesh, theBlock );
if ( aSubMesh )
{
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 )]);
}
}
myIsBoundaryPointsFound = true;
+ if ( myToKeepNodes )
+ {
+ myInNodes.resize( nodePointIDMap.size() );
+ TNodePointIDMap::iterator nIdIt = nodePointIDMap.begin();
+ for ( ; nIdIt != nodePointIDMap.end(); nIdIt++ )
+ myInNodes[ nIdIt->second ] = smdsNode( nIdIt->first );
+ }
+
return setErrorCode( ERR_OK );
}
+//=======================================================================
+//function : getSubmeshWithElements
+//purpose : return submesh containing elements bound to theBlock in theMesh
+//=======================================================================
+
+SMESHDS_SubMesh * SMESH_Pattern::getSubmeshWithElements(SMESH_Mesh* theMesh,
+ const TopoDS_Shape& theShape)
+{
+ SMESHDS_SubMesh * aSubMesh = theMesh->GetMeshDS()->MeshElements( theShape );
+ if ( aSubMesh && ( aSubMesh->GetElements()->more() || aSubMesh->GetNodes()->more() ))
+ return aSubMesh;
+
+ if ( theShape.ShapeType() == TopAbs_SHELL )
+ {
+ // look for submesh of VOLUME
+ TopTools_ListIteratorOfListOfShape it( theMesh->GetAncestors( theShape ));
+ for (; it.More(); it.Next()) {
+ aSubMesh = theMesh->GetMeshDS()->MeshElements( it.Value() );
+ if ( aSubMesh && ( aSubMesh->GetElements()->more() || aSubMesh->GetNodes()->more() ))
+ return aSubMesh;
+ }
+ }
+ return 0;
+}
+
+
//=======================================================================
//function : Apply
//purpose : Compute nodes coordinates applying
const TopoDS_Vertex& theVertex000,
const TopoDS_Vertex& theVertex001)
{
- MESSAGE(" ::Apply(volume) " );
-
if (!findBoundaryPoints() || // bind ID to points
!setShapeToMesh( theBlock )) // check theBlock is a suitable shape
return false;
const int theNode000Index,
const int theNode001Index)
{
- //MESSAGE(" ::Apply(MeshVolume) " );
-
if (!findBoundaryPoints()) // bind ID to points
return false;
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
myPolyElems.reserve( myIdsOnBoundary.size() );
// make a set of refined elements
- set< const SMDS_MeshElement* > avoidSet, elemSet;
- avoidSet.insert( myElements.begin(), myElements.end() );
+ TIDSortedElemSet elemSet, avoidSet( myElements.begin(), myElements.end() );
map< TNodeSet, list< list< int > > >::iterator indListIt, nn_IdList;
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 );
int i = 0, nbNodes = face->NbNodes();
vector<const SMDS_MeshNode*> nodes( nbNodes + 1 );
while ( nIt->more() )
- nodes[ i++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ nodes[ i++ ] = smdsNode( nIt->next() );
nodes[ i ] = nodes[ 0 ];
for ( i = 0; i < nbNodes; ++i )
{
// loop on nodes of refinedElem
SMDS_ElemIteratorPtr nIt = (*refinedElem)->nodesIterator();
while ( nIt->more() ) {
- const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ const SMDS_MeshNode* node = smdsNode( nIt->next() );
// loop on inverse elements of node
SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
while ( eIt->more() )
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;
}
+//=======================================================================
+//function : clearSubMesh
+//purpose :
+//=======================================================================
+
+static bool clearSubMesh( SMESH_Mesh* theMesh,
+ const TopoDS_Shape& theShape)
+{
+ bool removed = false;
+ if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMeshContaining( theShape ))
+ {
+ removed = !aSubMesh->IsEmpty();
+ if ( removed )
+ aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEAN );
+ }
+ else {
+ SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
+ if ( SMESHDS_SubMesh* aSubMeshDS = aMeshDS->MeshElements( theShape ))
+ {
+ SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
+ removed = eIt->more();
+ while ( eIt->more() )
+ aMeshDS->RemoveElement( eIt->next() );
+ SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
+ removed = removed || nIt->more();
+ while ( nIt->more() )
+ aMeshDS->RemoveNode( smdsNode( nIt->next() ));
+ }
+ }
+ return removed;
+}
+
//=======================================================================
//function : clearMesh
//purpose : clear mesh elements existing on myShape in theMesh
if ( !myShape.IsNull() )
{
- if ( SMESH_subMesh * aSubMesh = theMesh->GetSubMesh/*Containing*/( myShape ))
+ if ( !clearSubMesh( theMesh, myShape ) && !myIs2D ) { // myShape is SHELL but volumes may be bound to SOLID
+ TopTools_ListIteratorOfListOfShape it( theMesh->GetAncestors( myShape ));
+ for (; it.More() && it.Value().ShapeType() == TopAbs_SOLID; it.Next())
+ {
+ clearSubMesh( theMesh, it.Value() );
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : findExistingNodes
+//purpose : fills nodes vector with nodes existing on a given shape (IMP 22368)
+// Returns true if all nodes for all points on S are found
+//=======================================================================
+
+bool SMESH_Pattern::findExistingNodes( SMESH_Mesh* mesh,
+ const TopoDS_Shape& S,
+ const std::list< TPoint* > & points,
+ vector< const SMDS_MeshNode* > & nodesVector)
+{
+ if ( S.IsNull() || points.empty() )
+ return false;
+
+ SMESHDS_Mesh* aMeshDS = mesh->GetMeshDS();
+
+ switch ( S.ShapeType() )
+ {
+ case TopAbs_VERTEX:
+ {
+ int pIndex = points.back() - &myPoints[0];
+ if ( !nodesVector[ pIndex ] )
+ nodesVector[ pIndex ] = SMESH_Algo::VertexNode( TopoDS::Vertex( S ), aMeshDS );
+ return nodesVector[ pIndex ];
+ }
+ 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* >::const_reverse_iterator pItR = ++points.rbegin();
+ list< TPoint* >::const_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;
+ if ( paramsOfNodes.size() == points.size() )
{
- aSubMesh->ComputeStateEngine( SMESH_subMesh::CLEANDEP );
+ for ( ; u2n != u2nEnd; ++u2n )
+ {
+ p = ( isForward ? *pItF : *pItR );
+ int pIndex = p - &myPoints[0];
+ if ( !nodesVector [ pIndex ] )
+ nodesVector [ pIndex ] = u2n->second;
+ ++pItF;
+ ++pItR;
+ }
+ return true;
}
- else {
- SMESHDS_Mesh* aMeshDS = theMesh->GetMeshDS();
- if ( SMESHDS_SubMesh* aSubMeshDS = aMeshDS->MeshElements( myShape ))
+ else
+ {
+ const double tolFact = 0.05;
+ while ( u2n != u2nEnd && pItF != points.end() )
{
- SMDS_ElemIteratorPtr eIt = aSubMeshDS->GetElements();
- while ( eIt->more() )
- aMeshDS->RemoveElement( eIt->next() );
- SMDS_NodeIteratorPtr nIt = aSubMeshDS->GetNodes();
- while ( nIt->more() )
- aMeshDS->RemoveNode( static_cast<const SMDS_MeshNode*>( nIt->next() ));
+ const double u = u2n->first;
+ const SMDS_MeshNode* n = u2n->second;
+ const double tol = ( (++u2n)->first - u ) * tolFact;
+ 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;
+ } // case TopAbs_EDGE:
+
+ default:;
+ } // switch ( S.ShapeType() )
+
+ return false;
}
//=======================================================================
const bool toCreatePolygons,
const bool toCreatePolyedrs)
{
- MESSAGE(" ::MakeMesh() " );
if ( !myIsComputed )
return setErrorCode( ERR_MAKEM_NOT_COMPUTED );
for ( ; i_node != myXYZIdToNodeMap.end(); i_node++ ) {
nodesVector[ i_node->first ] = i_node->second;
}
- for ( int i = 0; i < myXYZ.size(); ++i ) {
+ for ( size_t i = 0; i < myXYZ.size(); ++i ) {
if ( !nodesVector[ i ] && isDefined( myXYZ[ i ] ) )
nodesVector[ i ] = aMeshDS->AddNode (myXYZ[ i ].X(),
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 ));
-
// loop on sub-shapes of myShape: create nodes
map< int, list< TPoint* > >::iterator idPointIt = myShapeIDToPointsMap.begin();
for ( ; idPointIt != myShapeIDToPointsMap.end(); idPointIt++ )
{
+ list< TPoint* > & points = idPointIt->second;
TopoDS_Shape S;
- SMESHDS_SubMesh * subMeshDS = 0;
- if ( !myShapeIDMap.IsEmpty() ) {
+ if ( !myShapeIDMap.IsEmpty() )
S = myShapeIDMap( idPointIt->first );
- subMeshDS = aMeshDS->MeshElements( S );
- }
- list< TPoint* > & points = idPointIt->second;
+
+ // find existing nodes on EDGEs and VERTEXes
+ if ( findExistingNodes( theMesh, S, points, nodesVector ))
+ continue;
+
list< TPoint* >::iterator pIt = points.begin();
for ( ; pIt != points.end(); pIt++ )
{
TPoint* point = *pIt;
- 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 ( subMeshDS ) {
+ if ( !S.IsNull() ) {
+
switch ( S.ShapeType() ) {
case TopAbs_VERTEX: {
- aMeshDS->SetNodeOnVertex( node, TopoDS::Vertex( S ));
- break;
+ aMeshDS->SetNodeOnVertex( node, TopoDS::Vertex( S )); break;
}
case TopAbs_EDGE: {
- aMeshDS->SetNodeOnEdge( node, TopoDS::Edge( S ));
- SMDS_EdgePosition* epos =
- dynamic_cast<SMDS_EdgePosition *>(node->GetPosition().get());
- epos->SetUParameter( point->myU );
- break;
+ aMeshDS->SetNodeOnEdge( node, TopoDS::Edge( S ), point->myU ); break;
}
case TopAbs_FACE: {
- aMeshDS->SetNodeOnFace( node, TopoDS::Face( S ));
- SMDS_FacePosition* pos =
- dynamic_cast<SMDS_FacePosition *>(node->GetPosition().get());
- pos->SetUParameter( point->myUV.X() );
- pos->SetVParameter( point->myUV.Y() );
- break;
+ aMeshDS->SetNodeOnFace( node, TopoDS::Face( S ),
+ point->myUV.X(), point->myUV.Y() ); break;
}
default:
aMeshDS->SetNodeInVolume( node, TopoDS::Shell( S ));
createElements( theMesh, nodesVector, myElemPointIDs, myElements );
}
+ aMeshDS->Modified();
+ aMeshDS->CompactMesh();
+
+ if ( myToKeepNodes )
+ myOutNodes.swap( nodesVector );
+
// 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();
groups.resize( theElements.size() );
const set<SMESHDS_GroupBase*>& allGroups = aMeshDS->GetGroups();
set<SMESHDS_GroupBase*>::const_iterator grIt;
- for ( int i = 0; i < theElements.size(); i++ )
+ for ( size_t i = 0; i < theElements.size(); i++ )
{
shapeIDs[ i ] = editor.FindShape( theElements[ i ] );
for ( grIt = allGroups.begin(); grIt != allGroups.end(); grIt++ ) {
TElemDef::const_iterator id = elemNodeInd.begin();
int nbNodes;
for ( nbNodes = 0; id != elemNodeInd.end(); id++ ) {
- if ( *id < theNodesVector.size() )
+ if ( *id < (int) theNodesVector.size() )
nodes[ nbNodes++ ] = theNodesVector[ *id ];
else
nodes[ nbNodes++ ] = myXYZIdToNodeMap[ *id ];
elem = aMeshDS->AddFace( nodes[0], nodes[1], nodes[2] ); break;
case 4:
elem = aMeshDS->AddFace( nodes[0], nodes[1], nodes[2], nodes[3] ); break;
+ case 6:
+ if ( !onMeshElements ) {// create a quadratic face
+ elem = aMeshDS->AddFace (nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5] ); break;
+ } // else do not break but create a polygon
+ case 8:
+ if ( !onMeshElements ) {// create a quadratic face
+ elem = aMeshDS->AddFace (nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7] ); break;
+ } // else do not break but create a polygon
default:
elem = aMeshDS->AddPolygonalFace( nodes );
}
}
SMDS_ElemIteratorPtr noIt = elem->nodesIterator();
while ( noIt->more() ) {
- SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>
- ( static_cast<const SMDS_MeshNode*>( noIt->next() ));
- if (!node->GetPosition()->GetShapeId() &&
- shellNodes.find( node ) == shellNodes.end() ) {
+ SMDS_MeshNode* node = const_cast<SMDS_MeshNode*>(smdsNode( noIt->next() ));
+ 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 );
SMESH_subMesh * subMesh;
if ( !myShape.IsNull() ) {
- subMesh = theMesh->GetSubMeshContaining( myShape );
+ subMesh = theMesh->GetSubMesh( myShape );
if ( subMesh )
subMesh->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
}
if ( onMeshElements ) {
list< int > elemIDs;
- for ( int i = 0; i < theElements.size(); i++ )
+ for ( size_t i = 0; i < theElements.size(); i++ )
{
subMesh = theMesh->GetSubMeshContaining( shapeIDs[ i ] );
if ( subMesh )
gp_Pnt P[2];
list<int>::const_iterator id = theIdsList.begin();
for ( int i = 0; i < 2; ++i, ++id ) {
- if ( *id < myXYZ.size() )
+ if ( *id < (int) myXYZ.size() )
P[ i ] = myXYZ[ *id ];
else {
map< int, const SMDS_MeshNode*>::const_iterator i_n;
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
}
if ( outerBndPos != boundaryList.begin() )
- boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos, ++outerBndPos );
+ boundaryList.splice( boundaryList.begin(), boundaryList, outerBndPos );
} // if nbBoundaries > 1
-
+
// Check boundaries orientation and re-fill myKeyPointIDs
set< TPoint* > keyPointSet;
{
if ( myIsBoundaryPointsFound ) return true;
- MESSAGE(" findBoundaryPoints() ");
+ myNbKeyPntInBoundary.clear();
if ( myIs2D )
{
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;
}
//=======================================================================
TopAbs_ShapeEnum aType = theShape.ShapeType();
bool dimOk = ( myIs2D ? aType == TopAbs_FACE : aType == TopAbs_SHELL );
if ( !dimOk ) {
- MESSAGE( "Pattern dimention mismatch" );
+ MESSAGE( "Pattern dimension mismatch" );
return setErrorCode( ERR_APPL_BAD_DIMENTION );
}
// 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 );
- if ( vMap.Extent() + nbNodeOnSeamEdge != myKeyPointIDs.size() ) {
- MESSAGE( myKeyPointIDs.size() << " != " << vMap.Extent() );
+ if ( vMap.Extent() + nbNodeOnSeamEdge != (int)myKeyPointIDs.size() ) {
+ MESSAGE( myKeyPointIDs.size() + nbNodeOnSeamEdge << " != " << vMap.Extent() );
return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
}
#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
}
SMESH_Pattern::TPoint::TPoint()
{
#ifdef _DEBUG_
- myInitXYZ.SetCoord(0,0,0);
- myInitUV.SetCoord(0.,0.);
- myInitU = 0;
- myXYZ.SetCoord(0,0,0);
- myUV.SetCoord(0.,0.);
- myU = 0;
+ myInitXYZ.SetCoord(7,7,7);
+ myInitUV.SetCoord(7.,7.);
+ myInitU = 7;
+ myXYZ.SetCoord(7,7,7);
+ myUV.SetCoord(7.,7.);
+ myU = 7;
#endif
}
OS << " uv( " << xy.X() << " " << xy.Y() << " )";
u = p.myU;
OS << " u( " << u << " ))" << endl;
-
+
return OS;
}