// Get nodes of the element
- const SMDS_QuadraticFaceOfNodes* F =
- static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
- if(F) {
+ if(anElem->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
// use special nodes iterator
SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
if ( anIter != 0 ) {
else if ( theNbNodes == 6 ) return VTK_WEDGE;
else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
else if ( theNbNodes == 10 ) {
- cout<<"QUADRATIC_TETRA"<<endl;
return VTK_QUADRATIC_TETRA;
}
else if ( theNbNodes == 20 ) {
- cout<<"QUADRATIC_HEXAHEDRON"<<endl;
return VTK_QUADRATIC_HEXAHEDRON;
}
else if ( theNbNodes==13 || theNbNodes==15 ) {
- cout<<"QUADRATIC - CONVEX_POINT_SET"<<endl;
return VTK_CONVEX_POINT_SET;
}
else return VTK_EMPTY_CELL;
if ( edge )
Ok = const_cast<SMDS_MeshEdge*>( edge )->ChangeNodes( nodes[0], nodes[1] );
}
+ else if ( nbnodes == 3 ) {
+ const SMDS_QuadraticEdge* edge = dynamic_cast<const SMDS_QuadraticEdge*>( elem );
+ if ( edge )
+ Ok = const_cast<SMDS_QuadraticEdge*>( edge )->ChangeNodes( nodes[0], nodes[1], nodes[2] );
+ }
break;
}
case SMDSAbs_Face: {
const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
if ( face ) {
Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
- } else {
- /// ??? begin
- const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
- if (face) {
- Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+ }
+ else {
+ const SMDS_QuadraticFaceOfNodes* QF =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*>( elem );
+ if ( QF ) {
+ Ok = const_cast<SMDS_QuadraticFaceOfNodes*>( QF )->ChangeNodes( nodes, nbnodes );
+ }
+ else {
+ /// ??? begin
+ const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+ if (face) {
+ Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+ }
+ /// ??? end
}
- /// ??? end
}
break;
}
//}
case SMDSAbs_Volume: {
const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
- if ( vol )
+ if ( vol ) {
Ok = const_cast<SMDS_VolumeOfNodes*>( vol )->ChangeNodes( nodes, nbnodes );
+ }
+ else {
+ const SMDS_QuadraticVolumeOfNodes* QV = dynamic_cast<const SMDS_QuadraticVolumeOfNodes*>( elem );
+ if ( QV ) {
+ Ok = const_cast<SMDS_QuadraticVolumeOfNodes*>( QV )->ChangeNodes( nodes, nbnodes );
+ }
+ }
break;
}
default:
return Ok;
}
+
//=======================================================================
//function : FindEdge
//purpose :
const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2) const
{
- const SMDS_MeshNode * node1=FindNode(idnode1);
- const SMDS_MeshNode * node2=FindNode(idnode2);
- if((node1==NULL)||(node2==NULL)) return NULL;
- return FindEdge(node1,node2);
+ const SMDS_MeshNode * node1=FindNode(idnode1);
+ const SMDS_MeshNode * node2=FindNode(idnode2);
+ if((node1==NULL)||(node2==NULL)) return NULL;
+ return FindEdge(node1,node2);
}
//#include "Profiler.h"
const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
const SMDS_MeshNode * node2)
{
- const SMDS_MeshEdge * toReturn=NULL;
- //PROFILER_Init();
- //PROFILER_Set();
- SMDS_ElemIteratorPtr it1=node1->edgesIterator();
- //PROFILER_Get(0);
- //PROFILER_Set();
- while(it1->more())
- {
- const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *>
- (it1->next());
- SMDS_ElemIteratorPtr it2=e->nodesIterator();
- while(it2->more())
- {
- if(it2->next()->GetID()==node2->GetID())
- {
- toReturn=e;
- break;
- }
- }
- }
- //PROFILER_Get(1);
- return toReturn;
+ const SMDS_MeshEdge * toReturn=NULL;
+ //PROFILER_Init();
+ //PROFILER_Set();
+ SMDS_ElemIteratorPtr it1=node1->edgesIterator();
+ //PROFILER_Get(0);
+ //PROFILER_Set();
+ while(it1->more()) {
+ const SMDS_MeshEdge * e=static_cast<const SMDS_MeshEdge *> (it1->next());
+ SMDS_ElemIteratorPtr it2=e->nodesIterator();
+ while(it2->more()) {
+ if(it2->next()->GetID()==node2->GetID()) {
+ toReturn = e;
+ break;
+ }
+ }
+ }
+ //PROFILER_Get(1);
+ return toReturn;
}
+//=======================================================================
+//function : FindEdgeOrCreate
+//purpose :
+//=======================================================================
+
SMDS_MeshEdge* SMDS_Mesh::FindEdgeOrCreate(const SMDS_MeshNode * node1,
- const SMDS_MeshNode * node2)
+ const SMDS_MeshNode * node2)
{
- SMDS_MeshEdge * toReturn=NULL;
- toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
- if(toReturn==NULL)
- {
- toReturn=new SMDS_MeshEdge(node1,node2);
- myEdges.Add(toReturn);
- }
- return toReturn;
+ SMDS_MeshEdge * toReturn=NULL;
+ toReturn=const_cast<SMDS_MeshEdge*>(FindEdge(node1,node2));
+ if(toReturn==NULL) {
+ toReturn=new SMDS_MeshEdge(node1,node2);
+ myEdges.Add(toReturn);
+ }
+ return toReturn;
+}
+
+
+//=======================================================================
+//function : FindEdge
+//purpose :
+//=======================================================================
+
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(int idnode1, int idnode2,
+ int idnode3) const
+{
+ const SMDS_MeshNode * node1=FindNode(idnode1);
+ const SMDS_MeshNode * node2=FindNode(idnode2);
+ const SMDS_MeshNode * node3=FindNode(idnode3);
+ if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL;
+ return FindEdge(node1,node2,node3);
+}
+
+const SMDS_MeshEdge* SMDS_Mesh::FindEdge(const SMDS_MeshNode * node1,
+ const SMDS_MeshNode * node2,
+ const SMDS_MeshNode * node3)
+{
+ const SMDS_MeshEdge * toReturn = NULL;
+ SMDS_ElemIteratorPtr it1 = node1->edgesIterator();
+ while(it1->more()) {
+ const SMDS_MeshEdge * e = static_cast<const SMDS_MeshEdge *> (it1->next());
+ SMDS_ElemIteratorPtr it2 = e->nodesIterator();
+ int tmp = 0;
+ while(it2->more()) {
+ int nID = it2->next()->GetID();
+ if( nID==node2->GetID() || nID==node3->GetID() ) {
+ tmp++;
+ if(tmp==2) {
+ toReturn = e;
+ break;
+ }
+ }
+ }
+ }
+ return toReturn;
}
+
//=======================================================================
//function : FindFace
//purpose :
const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
int idnode3) const
{
- const SMDS_MeshNode * node1=FindNode(idnode1);
- const SMDS_MeshNode * node2=FindNode(idnode2);
- const SMDS_MeshNode * node3=FindNode(idnode3);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)) return NULL;
- return FindFace(node1, node2, node3);
+ const SMDS_MeshNode * node1=FindNode(idnode1);
+ const SMDS_MeshNode * node2=FindNode(idnode2);
+ const SMDS_MeshNode * node3=FindNode(idnode3);
+ if( (node1==NULL) || (node2==NULL) || (node3==NULL) ) return NULL;
+ return FindFace(node1, node2, node3);
}
-const SMDS_MeshFace* SMDS_Mesh::FindFace(
- const SMDS_MeshNode *node1,
- const SMDS_MeshNode *node2,
- const SMDS_MeshNode *node3)
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3)
{
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- bool node2found, node3found;
-
- SMDS_ElemIteratorPtr it1=node1->facesIterator();
- while(it1->more())
- {
- face=static_cast<const SMDS_MeshFace*>(it1->next());
- if(face->NbNodes()!=3) continue;
- SMDS_ElemIteratorPtr it2=face->nodesIterator();
- node2found=false;
- node3found=false;
- while(it2->more())
- {
- node=it2->next();
- if(node->GetID()==node2->GetID()) node2found=true;
- if(node->GetID()==node3->GetID()) node3found=true;
- }
- if(node2found&&node3found)
- return face;
- }
- return NULL;
+ const SMDS_MeshFace * face;
+ const SMDS_MeshElement * node;
+ bool node2found, node3found;
+
+ SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ while(it1->more()) {
+ face = static_cast<const SMDS_MeshFace*>(it1->next());
+ if(face->NbNodes()!=3) continue;
+ SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+ node2found = false;
+ node3found = false;
+ while(it2->more()) {
+ node = it2->next();
+ if(node->GetID()==node2->GetID()) node2found = true;
+ if(node->GetID()==node3->GetID()) node3found = true;
+ }
+ if( node2found && node3found )
+ return face;
+ }
+ return NULL;
}
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
- const SMDS_MeshNode *node1,
- const SMDS_MeshNode *node2,
- const SMDS_MeshNode *node3)
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3)
{
- SMDS_MeshFace * toReturn=NULL;
- toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
- if(toReturn==NULL)
- {
- toReturn=createTriangle(node1,node2,node3);
- }
- return toReturn;
+ SMDS_MeshFace * toReturn=NULL;
+ toReturn = const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3));
+ if(toReturn==NULL) {
+ toReturn = createTriangle(node1,node2,node3);
+ }
+ return toReturn;
}
+
//=======================================================================
//function : FindFace
//purpose :
//=======================================================================
-const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2, int idnode3,
- int idnode4) const
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+ int idnode3, int idnode4) const
{
- const SMDS_MeshNode * node1=FindNode(idnode1);
- const SMDS_MeshNode * node2=FindNode(idnode2);
- const SMDS_MeshNode * node3=FindNode(idnode3);
- const SMDS_MeshNode * node4=FindNode(idnode4);
- if((node1==NULL)||(node2==NULL)||(node3==NULL)||(node4==NULL)) return NULL;
- return FindFace(node1, node2, node3, node4);
+ const SMDS_MeshNode * node1=FindNode(idnode1);
+ const SMDS_MeshNode * node2=FindNode(idnode2);
+ const SMDS_MeshNode * node3=FindNode(idnode3);
+ const SMDS_MeshNode * node4=FindNode(idnode4);
+ if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) )
+ return NULL;
+ return FindFace(node1, node2, node3, node4);
}
-const SMDS_MeshFace* SMDS_Mesh::FindFace(
- const SMDS_MeshNode *node1,
- const SMDS_MeshNode *node2,
- const SMDS_MeshNode *node3,
- const SMDS_MeshNode *node4)
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3,
+ const SMDS_MeshNode *node4)
{
- const SMDS_MeshFace * face;
- const SMDS_MeshElement * node;
- bool node2found, node3found, node4found;
- SMDS_ElemIteratorPtr it1=node1->facesIterator();
- while(it1->more())
- {
- face=static_cast<const SMDS_MeshFace *>(it1->next());
- if(face->NbNodes()!=4) continue;
- SMDS_ElemIteratorPtr it2=face->nodesIterator();
- node2found=false;
- node3found=false;
- node4found=false;
- while(it2->more())
- {
- node=it2->next();
- if(node->GetID()==node2->GetID()) node2found=true;
- if(node->GetID()==node3->GetID()) node3found=true;
- if(node->GetID()==node4->GetID()) node4found=true;
- }
- if(node2found&&node3found&&node4found)
- return face;
- }
- return NULL;
+ const SMDS_MeshFace * face;
+ const SMDS_MeshElement * node;
+ bool node2found, node3found, node4found;
+ SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ while(it1->more()) {
+ face = static_cast<const SMDS_MeshFace *>(it1->next());
+ if(face->NbNodes()!=4) continue;
+ SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+ node2found = false;
+ node3found = false;
+ node4found = false;
+ while(it2->more()) {
+ node=it2->next();
+ if(node->GetID()==node2->GetID()) node2found = true;
+ if(node->GetID()==node3->GetID()) node3found = true;
+ if(node->GetID()==node4->GetID()) node4found = true;
+ }
+ if( node2found && node3found && node4found )
+ return face;
+ }
+ return NULL;
}
-SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(
- const SMDS_MeshNode *node1,
- const SMDS_MeshNode *node2,
- const SMDS_MeshNode *node3,
- const SMDS_MeshNode *node4)
+SMDS_MeshFace* SMDS_Mesh::FindFaceOrCreate(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3,
+ const SMDS_MeshNode *node4)
{
- SMDS_MeshFace * toReturn=NULL;
- toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
- if(toReturn==NULL)
- {
- toReturn=createQuadrangle(node1,node2,node3,node4);
- }
- return toReturn;
+ SMDS_MeshFace * toReturn=NULL;
+ toReturn=const_cast<SMDS_MeshFace*>(FindFace(node1,node2,node3,node4));
+ if(toReturn==NULL) {
+ toReturn=createQuadrangle(node1,node2,node3,node4);
+ }
+ return toReturn;
+}
+
+
+//=======================================================================
+//function : FindFace
+//purpose :quadratic triangle
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+ int idnode3, int idnode4,
+ int idnode5, int idnode6) const
+{
+ const SMDS_MeshNode * node1 = FindNode(idnode1);
+ const SMDS_MeshNode * node2 = FindNode(idnode2);
+ const SMDS_MeshNode * node3 = FindNode(idnode3);
+ const SMDS_MeshNode * node4 = FindNode(idnode4);
+ const SMDS_MeshNode * node5 = FindNode(idnode5);
+ const SMDS_MeshNode * node6 = FindNode(idnode6);
+ if( (node1==NULL) || (node2==NULL) || (node3==NULL) ||
+ (node4==NULL) || (node5==NULL) || (node6==NULL) ) return NULL;
+ return FindFace(node1, node2, node3, node4, node5, node6);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3,
+ const SMDS_MeshNode *node4,
+ const SMDS_MeshNode *node5,
+ const SMDS_MeshNode *node6)
+{
+ const SMDS_MeshFace * face;
+ const SMDS_MeshElement * node;
+ SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ while(it1->more()) {
+ face = static_cast<const SMDS_MeshFace*>(it1->next());
+ if(face->NbNodes()!=6) continue;
+ SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+ int tmp = 0;
+ while(it2->more()) {
+ node = it2->next();
+ if(node->GetID()==node2->GetID()) tmp++;
+ if(node->GetID()==node3->GetID()) tmp++;
+ if(node->GetID()==node4->GetID()) tmp++;
+ if(node->GetID()==node5->GetID()) tmp++;
+ if(node->GetID()==node6->GetID()) tmp++;
+ }
+ if( tmp==5 )
+ return static_cast<const SMDS_MeshFace*>(face);
+ }
+ return NULL;
+}
+
+
+//=======================================================================
+//function : FindFace
+//purpose : quadratic quadrangle
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(int idnode1, int idnode2,
+ int idnode3, int idnode4,
+ int idnode5, int idnode6,
+ int idnode7, int idnode8) const
+{
+ const SMDS_MeshNode * node1 = FindNode(idnode1);
+ const SMDS_MeshNode * node2 = FindNode(idnode2);
+ const SMDS_MeshNode * node3 = FindNode(idnode3);
+ const SMDS_MeshNode * node4 = FindNode(idnode4);
+ const SMDS_MeshNode * node5 = FindNode(idnode5);
+ const SMDS_MeshNode * node6 = FindNode(idnode6);
+ const SMDS_MeshNode * node7 = FindNode(idnode7);
+ const SMDS_MeshNode * node8 = FindNode(idnode8);
+ if( (node1==NULL) || (node2==NULL) || (node3==NULL) || (node4==NULL) ||
+ (node5==NULL) || (node6==NULL) || (node7==NULL) || (node8==NULL) )
+ return NULL;
+ return FindFace(node1, node2, node3, node4, node5, node6, node7, node8);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace(const SMDS_MeshNode *node1,
+ const SMDS_MeshNode *node2,
+ const SMDS_MeshNode *node3,
+ const SMDS_MeshNode *node4,
+ const SMDS_MeshNode *node5,
+ const SMDS_MeshNode *node6,
+ const SMDS_MeshNode *node7,
+ const SMDS_MeshNode *node8)
+{
+ const SMDS_MeshFace * face;
+ const SMDS_MeshElement * node;
+ SMDS_ElemIteratorPtr it1 = node1->facesIterator();
+ while(it1->more()) {
+ face = static_cast<const SMDS_MeshFace *>(it1->next());
+ if(face->NbNodes()!=8) continue;
+ SMDS_ElemIteratorPtr it2 = face->nodesIterator();
+ int tmp = 0;
+ while(it2->more()) {
+ node = it2->next();
+ if(node->GetID()==node2->GetID()) tmp++;
+ if(node->GetID()==node3->GetID()) tmp++;
+ if(node->GetID()==node4->GetID()) tmp++;
+ if(node->GetID()==node5->GetID()) tmp++;
+ if(node->GetID()==node6->GetID()) tmp++;
+ if(node->GetID()==node7->GetID()) tmp++;
+ if(node->GetID()==node8->GetID()) tmp++;
+ }
+ if( tmp==7 )
+ return face;
+ }
+ return NULL;
}
+
//=======================================================================
//function : FindElement
//purpose :
const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
{
- return myElementIDFactory->MeshElement(IDelem);
+ return myElementIDFactory->MeshElement(IDelem);
}
//=======================================================================
const SMDS_MeshNode * n12,
const SMDS_MeshNode * n23,
const SMDS_MeshNode * n34,
- const SMDS_MeshNode * n51,
+ const SMDS_MeshNode * n41,
const SMDS_MeshNode * n56,
const SMDS_MeshNode * n67,
const SMDS_MeshNode * n78,
const SMDS_MeshNode * n12,
const SMDS_MeshNode * n23,
const SMDS_MeshNode * n34,
- const SMDS_MeshNode * n51,
+ const SMDS_MeshNode * n41,
const SMDS_MeshNode * n56,
const SMDS_MeshNode * n67,
const SMDS_MeshNode * n78,
const SMDS_MeshNode *FindNode(int idnode) const;
const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2) const;
+ const SMDS_MeshEdge *FindEdge(int idnode1, int idnode2, int idnode3) const;
const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3) const;
const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4) const;
+ const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3,
+ int idnode4, int idnode5, int idnode6) const;
+ const SMDS_MeshFace *FindFace(int idnode1, int idnode2, int idnode3, int idnode4,
+ int idnode5, int idnode6, int idnode7, int idnode8) const;
const SMDS_MeshElement *FindElement(int IDelem) const;
static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
const SMDS_MeshNode * n2);
+ static const SMDS_MeshEdge* FindEdge(const SMDS_MeshNode * n1,
+ const SMDS_MeshNode * n2,
+ const SMDS_MeshNode * n3);
static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
const SMDS_MeshNode *n2,
const SMDS_MeshNode *n3);
const SMDS_MeshNode *n2,
const SMDS_MeshNode *n3,
const SMDS_MeshNode *n4);
+ static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3,
+ const SMDS_MeshNode *n4,
+ const SMDS_MeshNode *n5,
+ const SMDS_MeshNode *n6);
+ static const SMDS_MeshFace* FindFace(const SMDS_MeshNode *n1,
+ const SMDS_MeshNode *n2,
+ const SMDS_MeshNode *n3,
+ const SMDS_MeshNode *n4,
+ const SMDS_MeshNode *n5,
+ const SMDS_MeshNode *n6,
+ const SMDS_MeshNode *n7,
+ const SMDS_MeshNode *n8);
const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> nodes);
return false;
}
-bool SMDS_MeshElement::IsMediumNode(class SMDS_MeshNode* node) const
+bool SMDS_MeshElement::IsMediumNode(const SMDS_MeshNode* node) const
{
return false;
}
virtual bool IsPoly() const { return false; };
virtual bool IsQuadratic() const;
- virtual bool IsMediumNode(class SMDS_MeshNode* node) const;
+ virtual bool IsMediumNode(const SMDS_MeshNode* node) const;
friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
XYZ aVec13( p3 - p1 );
XYZ cross = aVec12.Crossed( aVec13 );
- if ( myFaceNbNodes == 4 ) {
+ //if ( myFaceNbNodes == 4 ) {
+ if ( myFaceNbNodes >3 ) {
XYZ p4 ( myFaceNodes[3] );
XYZ aVec14( p4 - p1 );
XYZ cross2 = aVec13.Crossed( aVec14 );
bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
const int theNode2Index) const
{
- if (myVolume->IsPoly()) {
+ if ( myVolume->IsPoly() ) {
return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
}
default:;
}
break;
+ case 10:
+ {
+ switch ( minInd ) {
+ case 0: if( maxInd==4 || maxInd==6 || maxInd==7 ) return true;
+ case 1: if( maxInd==4 || maxInd==5 || maxInd==8 ) return true;
+ case 2: if( maxInd==5 || maxInd==6 || maxInd==9 ) return true;
+ case 3: if( maxInd==7 || maxInd==8 || maxInd==9 ) return true;
+ default:;
+ }
+ break;
+ }
+ case 13:
+ {
+ switch ( minInd ) {
+ case 0: if( maxInd==5 || maxInd==8 || maxInd==9 ) return true;
+ case 1: if( maxInd==5 || maxInd==6 || maxInd==10 ) return true;
+ case 2: if( maxInd==6 || maxInd==7 || maxInd==11 ) return true;
+ case 3: if( maxInd==7 || maxInd==8 || maxInd==12 ) return true;
+ case 4: if( maxInd==9 || maxInd==10 || maxInd==11 || maxInd==12 ) return true;
+ default:;
+ }
+ break;
+ }
+ case 15:
+ {
+ switch ( minInd ) {
+ case 0: if( maxInd==6 || maxInd==8 || maxInd==12 ) return true;
+ case 1: if( maxInd==6 || maxInd==7 || maxInd==13 ) return true;
+ case 2: if( maxInd==7 || maxInd==8 || maxInd==14 ) return true;
+ case 3: if( maxInd==9 || maxInd==11 || maxInd==12 ) return true;
+ case 4: if( maxInd==9 || maxInd==10 || maxInd==13 ) return true;
+ case 5: if( maxInd==10 || maxInd==11 || maxInd==14 ) return true;
+ default:;
+ }
+ break;
+ }
+ case 20:
+ {
+ switch ( minInd ) {
+ case 0: if( maxInd==8 || maxInd==11 || maxInd==16 ) return true;
+ case 1: if( maxInd==8 || maxInd==9 || maxInd==17 ) return true;
+ case 2: if( maxInd==9 || maxInd==10 || maxInd==18 ) return true;
+ case 3: if( maxInd==10 || maxInd==11 || maxInd==19 ) return true;
+ case 4: if( maxInd==12 || maxInd==15 || maxInd==16 ) return true;
+ case 5: if( maxInd==12 || maxInd==13 || maxInd==17 ) return true;
+ case 6: if( maxInd==13 || maxInd==14 || maxInd==18 ) return true;
+ case 7: if( maxInd==14 || maxInd==15 || maxInd==19 ) return true;
+ default:;
+ }
+ break;
+ }
default:;
}
return false;
typedef map< const SMDS_MeshElement*, int > TElemIntMap;
TElemIntMap volNbShared;
TElemIntMap::iterator vNbIt;
- for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
- {
+ for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
const SMDS_MeshNode* n = nodes[ iNode ];
SMDS_ElemIteratorPtr eIt = n->GetInverseElementIterator();
while ( eIt->more() ) {
if ( elem != myVolume && elem->GetType() == SMDSAbs_Volume ) {
int nbShared = 1;
vNbIt = volNbShared.find( elem );
- if ( vNbIt == volNbShared.end() )
+ if ( vNbIt == volNbShared.end() ) {
volNbShared.insert ( TElemIntMap::value_type( elem, nbShared ));
- else
+ }
+ else {
nbShared = ++(*vNbIt).second;
+ }
if ( nbShared > maxNbShared )
maxNbShared = nbShared;
}
if ( IsFaceExternal( faceIndex ))
intNormal = XYZ( -intNormal.x, -intNormal.y, -intNormal.z );
XYZ p0 ( nodes[0] ), baryCenter;
- for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ )
- {
+ for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
int nbShared = (*vNbIt).second;
if ( nbShared >= 3 ) {
SMDS_VolumeTool volume( (*vNbIt).first );
// remove a volume from volNbShared map
volNbShared.erase( vNbIt );
}
+
// here volNbShared contains only volumes laying on the
// opposite side of the face
- if ( volNbShared.empty() )
+ if ( volNbShared.empty() ) {
return free; // is free
+ }
// check if the whole area of a face is shared
bool isShared[] = { false, false, false, false }; // 4 triangle parts of a quadrangle
- for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ )
- {
+ for ( vNbIt = volNbShared.begin(); vNbIt != volNbShared.end(); vNbIt++ ) {
SMDS_VolumeTool volume( (*vNbIt).first );
bool prevLinkShared = false;
int nbSharedLinks = 0;
- for ( int iNode = 0; iNode < nbFaceNodes; iNode++ )
- {
+ for ( int iNode = 0; iNode < nbFaceNodes; iNode++ ) {
bool linkShared = volume.IsLinked( nodes[ iNode ], nodes[ iNode + 1] );
if ( linkShared )
nbSharedLinks++;
using namespace std;
#include "SMESH_2D_Algo.hxx"
#include "SMESH_Gen.hxx"
-#include "SMESH_subMesh.hxx"
+#include <TopExp.hxx>
#include "utilities.h"
// _compatibleHypothesis.push_back("hypothese_2D_bidon");
_type = ALGO_2D;
gen->_map2D_Algo[hypId] = this;
+ myCreateQuadratic = false;
}
//=============================================================================
SMESH_2D_Algo::~SMESH_2D_Algo()
{
+ myCreateQuadratic = false;
}
//=============================================================================
int SMESH_2D_Algo::NumberOfPoints(SMESH_Mesh& aMesh, const TopoDS_Wire& W)
{
int nbPoints = 0;
- for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next())
- {
- const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
- int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- //SCRUTE(nb);
- nbPoints += nb +1; // internal points plus 1 vertex of 2 (last point ?)
- }
+ for (TopExp_Explorer exp(W,TopAbs_EDGE); exp.More(); exp.Next()) {
+ const TopoDS_Edge& E = TopoDS::Edge(exp.Current());
+ int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
+ if(myCreateQuadratic)
+ nb = nb/2;
+ //SCRUTE(nb);
+ nbPoints += nb +1; // internal points plus 1 vertex of 2 (last point ?)
+ }
//SCRUTE(nbPoints);
return nbPoints;
}
+
+
#define _SMESH_2D_ALGO_HXX_
#include "SMESH_Algo.hxx"
-#include <TopoDS_Wire.hxx>
+#include "SMESH_subMesh.hxx"
+#include "TopoDS_Wire.hxx"
class SMESH_2D_Algo:
public SMESH_Algo
int NumberOfWires(const TopoDS_Shape& S);
int NumberOfPoints(SMESH_Mesh& aMesh,const TopoDS_Wire& W);
+
+protected:
+ bool myCreateQuadratic;
};
#endif
using namespace std;
#include "SMESH_3D_Algo.hxx"
#include "SMESH_Gen.hxx"
-#include "SMESH_subMesh.hxx"
#include "utilities.h"
SMESH_3D_Algo::~SMESH_3D_Algo()
{
}
+
+
public:
SMESH_3D_Algo(int hypId, int studyId, SMESH_Gen* gen);
virtual ~SMESH_3D_Algo();
+
};
#endif
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
+#include <gp_XY.hxx>
#include <string>
#include <vector>
#include <list>
+#include <map>
class SMESH_Gen;
class SMESH_Mesh;
class TopoDS_Face;
class SMESHDS_Mesh;
+class SMDS_MeshNode;
class SMESH_Algo:public SMESH_Hypothesis
{
std::vector<std::string> _compatibleHypothesis;
std::list<const SMESHDS_Hypothesis *> _appliedHypList;
std::list<const SMESHDS_Hypothesis *> _usedHypList;
+
};
#endif
const SMDS_MeshFace * curFace;
while (itFaces->more()) {
curFace = itFaces->next();
- if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++;
+ if ( !curFace->IsPoly() &&
+ ( curFace->NbNodes()==3 || curFace->NbNodes()==6 ) ) Nb++;
}
return Nb;
}
const SMDS_MeshFace * curFace;
while (itFaces->more()) {
curFace = itFaces->next();
- if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++;
+ if ( !curFace->IsPoly() &&
+ ( curFace->NbNodes() == 4 || curFace->NbNodes()==8 ) ) Nb++;
}
return Nb;
}
const SMDS_MeshVolume * curVolume;
while (itVolumes->more()) {
curVolume = itVolumes->next();
- if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++;
+ if ( !curVolume->IsPoly() &&
+ ( curVolume->NbNodes() == 4 || curVolume->NbNodes()==10 ) ) Nb++;
}
return Nb;
}
const SMDS_MeshVolume * curVolume;
while (itVolumes->more()) {
curVolume = itVolumes->next();
- if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++;
+ if ( !curVolume->IsPoly() &&
+ ( curVolume->NbNodes() == 8 || curVolume->NbNodes()==20 ) ) Nb++;
}
return Nb;
}
const SMDS_MeshVolume * curVolume;
while (itVolumes->more()) {
curVolume = itVolumes->next();
- if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++;
+ if ( !curVolume->IsPoly() &&
+ ( curVolume->NbNodes() == 5 || curVolume->NbNodes()==13 ) ) Nb++;
}
return Nb;
}
const SMDS_MeshVolume * curVolume;
while (itVolumes->more()) {
curVolume = itVolumes->next();
- if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++;
+ if ( !curVolume->IsPoly() &&
+ ( curVolume->NbNodes() == 6 || curVolume->NbNodes()==15 ) ) Nb++;
}
return Nb;
}
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMDS_FacePosition.hxx"
#include "SMDS_SpacePosition.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
typedef map<const SMDS_MeshElement*, list<const SMDS_MeshElement*> > TElemOfElemListMap;
typedef map<const SMDS_MeshNode*, list<const SMDS_MeshNode*> > TNodeOfNodeListMap;
typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr;
+//typedef map<const SMDS_MeshNode*, vector<const SMDS_MeshNode*> > TNodeOfNodeVecMap;
+//typedef TNodeOfNodeVecMap::iterator TNodeOfNodeVecMapItr;
typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeListMapItr> > TElemOfVecOfNnlmiMap;
+//typedef map<const SMDS_MeshElement*, vector<TNodeOfNodeVecMapItr> > TElemOfVecOfMapNodesMap;
+typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> NLink;
//=======================================================================
//function : SMESH_MeshEditor
set< SMESH_subMesh *> smmap;
list<int>::const_iterator it = theIDs.begin();
- for ( ; it != theIDs.end(); it++ )
- {
+ for ( ; it != theIDs.end(); it++ ) {
const SMDS_MeshElement * elem;
if ( isNodes )
elem = aMesh->FindNode( *it );
// Find sub-meshes to notify about modification
SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
- while ( nodeIt->more() )
- {
+ while ( nodeIt->more() ) {
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
const SMDS_PositionPtr& aPosition = node->GetPosition();
if ( aPosition.get() ) {
for ( smIt = smmap.begin(); smIt != smmap.end(); smIt++ )
(*smIt)->ComputeStateEngine( SMESH_subMesh::MESH_ENTITY_REMOVED );
}
+
return true;
}
if ( aMesh->ShapeToMesh().IsNull() )
return 0;
- if ( theElem->GetType() == SMDSAbs_Node )
- {
+ if ( theElem->GetType() == SMDSAbs_Node ) {
const SMDS_PositionPtr& aPosition =
static_cast<const SMDS_MeshNode*>( theElem )->GetPosition();
if ( aPosition.get() )
TopoDS_Shape aShape; // the shape a node is on
SMDS_ElemIteratorPtr nodeIt = theElem->nodesIterator();
- while ( nodeIt->more() )
- {
+ while ( nodeIt->more() ) {
const SMDS_MeshNode* node = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
const SMDS_PositionPtr& aPosition = node->GetPosition();
if ( aPosition.get() ) {
- int aShapeID = aPosition->GetShapeId();
- SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
- if ( sm )
- {
- if ( sm->Contains( theElem ))
- return aShapeID;
- if ( aShape.IsNull() )
- aShape = aMesh->IndexToShape( aShapeID );
- }
- else
- {
- //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID );
- }
+ int aShapeID = aPosition->GetShapeId();
+ SMESHDS_SubMesh * sm = aMesh->MeshElements( aShapeID );
+ if ( sm ) {
+ if ( sm->Contains( theElem ))
+ return aShapeID;
+ if ( aShape.IsNull() )
+ aShape = aMesh->IndexToShape( aShapeID );
+ }
+ else {
+ //MESSAGE ( "::FindShape() No SubShape for aShapeID " << aShapeID );
}
+ }
}
// None of nodes is on a proper shape,
return 0;
}
TopTools_ListIteratorOfListOfShape ancIt( GetMesh()->GetAncestors( aShape ));
- for ( ; ancIt.More(); ancIt.Next() )
- {
- SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
- if ( sm && sm->Contains( theElem ))
- return aMesh->ShapeToIndex( ancIt.Value() );
+ for ( ; ancIt.More(); ancIt.Next() ) {
+ SMESHDS_SubMesh * sm = aMesh->MeshElements( ancIt.Value() );
+ if ( sm && sm->Contains( theElem ))
+ return aMesh->ShapeToIndex( ancIt.Value() );
}
//MESSAGE ("::FindShape() - SHAPE NOT FOUND")
return 0;
}
+//=======================================================================
+//function : ShiftNodesQuadTria
+//purpose : auxilary
+// Shift nodes in the array corresponded to quadratic triangle
+// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3)
+//=======================================================================
+static void ShiftNodesQuadTria(const SMDS_MeshNode* aNodes[])
+{
+ const SMDS_MeshNode* nd1 = aNodes[0];
+ aNodes[0] = aNodes[1];
+ aNodes[1] = aNodes[2];
+ aNodes[2] = nd1;
+ const SMDS_MeshNode* nd2 = aNodes[3];
+ aNodes[3] = aNodes[4];
+ aNodes[4] = aNodes[5];
+ aNodes[5] = nd2;
+}
+
+//=======================================================================
+//function : GetNodesFromTwoTria
+//purpose : auxilary
+// Shift nodes in the array corresponded to quadratic triangle
+// example: (0,1,2,3,4,5) -> (1,2,0,4,5,3)
+//=======================================================================
+static bool GetNodesFromTwoTria(const SMDS_MeshElement * theTria1,
+ const SMDS_MeshElement * theTria2,
+ const SMDS_MeshNode* N1[],
+ const SMDS_MeshNode* N2[])
+{
+ SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
+ int i=0;
+ while(i<6) {
+ N1[i] = static_cast<const SMDS_MeshNode*>( it->next() );
+ i++;
+ }
+ if(it->more()) return false;
+ it = theTria2->nodesIterator();
+ i=0;
+ while(i<6) {
+ N2[i] = static_cast<const SMDS_MeshNode*>( it->next() );
+ i++;
+ }
+ if(it->more()) return false;
+
+ int sames[3] = {-1,-1,-1};
+ int nbsames = 0;
+ int j;
+ for(i=0; i<3; i++) {
+ for(j=0; j<3; j++) {
+ if(N1[i]==N2[j]) {
+ sames[i] = j;
+ nbsames++;
+ break;
+ }
+ }
+ }
+ if(nbsames!=2) return false;
+ if(sames[0]>-1) {
+ ShiftNodesQuadTria(N1);
+ if(sames[1]>-1) {
+ ShiftNodesQuadTria(N1);
+ }
+ }
+ i = sames[0] + sames[1] + sames[2];
+ for(; i<2; i++) {
+ ShiftNodesQuadTria(N2);
+ }
+ // now we receive following N1 and N2 (using numeration as above image)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // i.e. first nodes from both arrays determ new diagonal
+ return true;
+}
+
//=======================================================================
//function : InverseDiag
//purpose : Replace two neighbour triangles with ones built on the same 4 nodes
{
if (!theTria1 || !theTria2)
return false;
+
const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria1 );
- if (!F1) return false;
const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( theTria2 );
- if (!F2) return false;
+ if (F1 && F2) {
- // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
- // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
- // |/ | | \|
- // B +--+ 2 B +--+ 2
+ // 1 +--+ A theTria1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
+ // | /| theTria2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
+ // |/ | | \|
+ // B +--+ 2 B +--+ 2
- // put nodes in array and find out indices of the same ones
- const SMDS_MeshNode* aNodes [6];
- int sameInd [] = { 0, 0, 0, 0, 0, 0 };
- int i = 0;
- SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
- while ( it->more() )
- {
- aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
-
- if ( i > 2 ) // theTria2
- // find same node of theTria1
- for ( int j = 0; j < 3; j++ )
- if ( aNodes[ i ] == aNodes[ j ]) {
- sameInd[ j ] = i;
- sameInd[ i ] = j;
- break;
- }
- // next
- i++;
- if ( i == 3 ) {
- if ( it->more() )
- return false; // theTria1 is not a triangle
- it = theTria2->nodesIterator();
+ // put nodes in array and find out indices of the same ones
+ const SMDS_MeshNode* aNodes [6];
+ int sameInd [] = { 0, 0, 0, 0, 0, 0 };
+ int i = 0;
+ SMDS_ElemIteratorPtr it = theTria1->nodesIterator();
+ while ( it->more() ) {
+ aNodes[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+
+ if ( i > 2 ) // theTria2
+ // find same node of theTria1
+ for ( int j = 0; j < 3; j++ )
+ if ( aNodes[ i ] == aNodes[ j ]) {
+ sameInd[ j ] = i;
+ sameInd[ i ] = j;
+ break;
+ }
+ // next
+ i++;
+ if ( i == 3 ) {
+ if ( it->more() )
+ return false; // theTria1 is not a triangle
+ it = theTria2->nodesIterator();
+ }
+ if ( i == 6 && it->more() )
+ return false; // theTria2 is not a triangle
}
- if ( i == 6 && it->more() )
- return false; // theTria2 is not a triangle
- }
+
+ // find indices of 1,2 and of A,B in theTria1
+ int iA = 0, iB = 0, i1 = 0, i2 = 0;
+ for ( i = 0; i < 6; i++ ) {
+ if ( sameInd [ i ] == 0 )
+ if ( i < 3 ) i1 = i;
+ else i2 = i;
+ else if (i < 3)
+ if ( iA ) iB = i;
+ else iA = i;
+ }
+ // nodes 1 and 2 should not be the same
+ if ( aNodes[ i1 ] == aNodes[ i2 ] )
+ return false;
+
+ // theTria1: A->2
+ aNodes[ iA ] = aNodes[ i2 ];
+ // theTria2: B->1
+ aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
+
+ //MESSAGE( theTria1 << theTria2 );
+
+ GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
+ GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
+
+ //MESSAGE( theTria1 << theTria2 );
- // find indices of 1,2 and of A,B in theTria1
- int iA = 0, iB = 0, i1 = 0, i2 = 0;
- for ( i = 0; i < 6; i++ )
- {
- if ( sameInd [ i ] == 0 )
- if ( i < 3 ) i1 = i;
- else i2 = i;
- else if (i < 3)
- if ( iA ) iB = i;
- else iA = i;
- }
- // nodes 1 and 2 should not be the same
- if ( aNodes[ i1 ] == aNodes[ i2 ] )
+ return true;
+
+ } // end if(F1 && F2)
+
+ // check case of quadratic faces
+ const SMDS_QuadraticFaceOfNodes* QF1 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria1);
+ if(!QF1) return false;
+ const SMDS_QuadraticFaceOfNodes* QF2 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (theTria2);
+ if(!QF2) return false;
+
+ // 5
+ // 1 +--+--+ 2 theTria1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
+ // | /| theTria2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
+ // | / |
+ // 7 + + + 6
+ // | /9 |
+ // |/ |
+ // 4 +--+--+ 3
+ // 8
+
+ const SMDS_MeshNode* N1 [6];
+ const SMDS_MeshNode* N2 [6];
+ if(!GetNodesFromTwoTria(theTria1,theTria2,N1,N2))
return false;
-
-
- // theTria1: A->2
- aNodes[ iA ] = aNodes[ i2 ];
- // theTria2: B->1
- aNodes[ sameInd[ iB ]] = aNodes[ i1 ];
-
- //MESSAGE( theTria1 << theTria2 );
-
- GetMeshDS()->ChangeElementNodes( theTria1, aNodes, 3 );
- GetMeshDS()->ChangeElementNodes( theTria2, &aNodes[ 3 ], 3 );
-
- //MESSAGE( theTria1 << theTria2 );
+ // now we receive following N1 and N2 (using numeration as above image)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // i.e. first nodes from both arrays determ new diagonal
+
+ const SMDS_MeshNode* N1new [6];
+ const SMDS_MeshNode* N2new [6];
+ N1new[0] = N1[0];
+ N1new[1] = N2[0];
+ N1new[2] = N2[1];
+ N1new[3] = N1[4];
+ N1new[4] = N2[3];
+ N1new[5] = N1[5];
+ N2new[0] = N1[0];
+ N2new[1] = N1[1];
+ N2new[2] = N2[0];
+ N2new[3] = N1[3];
+ N2new[4] = N2[5];
+ N2new[5] = N1[4];
+ // replaces nodes in faces
+ GetMeshDS()->ChangeElementNodes( theTria1, N1new, 6 );
+ GetMeshDS()->ChangeElementNodes( theTria2, N2new, 6 );
return true;
}
if ( theTria1 ) {
theTria2 = elem;
break;
- } else {
+ }
+ else {
theTria1 = elem;
}
}
return false;
const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
- if (!F1) return false;
+ //if (!F1) return false;
const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
- if (!F2) return false;
-
- // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
- // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
- // |/ | | \|
- // B +--+ 2 B +--+ 2
-
- // put nodes in array
- // and find indices of 1,2 and of A in tr1 and of B in tr2
- int i, iA1 = 0, i1 = 0;
- const SMDS_MeshNode* aNodes1 [3];
- SMDS_ElemIteratorPtr it;
- for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) {
- aNodes1[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
- if ( aNodes1[ i ] == theNode1 )
- iA1 = i; // node A in tr1
- else if ( aNodes1[ i ] != theNode2 )
- i1 = i; // node 1
- }
- int iB2 = 0, i2 = 0;
- const SMDS_MeshNode* aNodes2 [3];
- for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) {
- aNodes2[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
- if ( aNodes2[ i ] == theNode2 )
- iB2 = i; // node B in tr2
- else if ( aNodes2[ i ] != theNode1 )
- i2 = i; // node 2
- }
-
- // nodes 1 and 2 should not be the same
- if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
- return false;
-
- // tr1: A->2
- aNodes1[ iA1 ] = aNodes2[ i2 ];
- // tr2: B->1
- aNodes2[ iB2 ] = aNodes1[ i1 ];
+ //if (!F2) return false;
+ if (F1 && F2) {
+
+ // 1 +--+ A tr1: ( 1 A B ) A->2 ( 1 2 B ) 1 +--+ A
+ // | /| tr2: ( B A 2 ) B->1 ( 1 A 2 ) |\ |
+ // |/ | | \|
+ // B +--+ 2 B +--+ 2
+
+ // put nodes in array
+ // and find indices of 1,2 and of A in tr1 and of B in tr2
+ int i, iA1 = 0, i1 = 0;
+ const SMDS_MeshNode* aNodes1 [3];
+ SMDS_ElemIteratorPtr it;
+ for (i = 0, it = tr1->nodesIterator(); it->more(); i++ ) {
+ aNodes1[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+ if ( aNodes1[ i ] == theNode1 )
+ iA1 = i; // node A in tr1
+ else if ( aNodes1[ i ] != theNode2 )
+ i1 = i; // node 1
+ }
+ int iB2 = 0, i2 = 0;
+ const SMDS_MeshNode* aNodes2 [3];
+ for (i = 0, it = tr2->nodesIterator(); it->more(); i++ ) {
+ aNodes2[ i ] = static_cast<const SMDS_MeshNode*>( it->next() );
+ if ( aNodes2[ i ] == theNode2 )
+ iB2 = i; // node B in tr2
+ else if ( aNodes2[ i ] != theNode1 )
+ i2 = i; // node 2
+ }
+
+ // nodes 1 and 2 should not be the same
+ if ( aNodes1[ i1 ] == aNodes2[ i2 ] )
+ return false;
- //MESSAGE( tr1 << tr2 );
+ // tr1: A->2
+ aNodes1[ iA1 ] = aNodes2[ i2 ];
+ // tr2: B->1
+ aNodes2[ iB2 ] = aNodes1[ i1 ];
- GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
- GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
+ //MESSAGE( tr1 << tr2 );
- //MESSAGE( tr1 << tr2 );
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes1, 3 );
+ GetMeshDS()->ChangeElementNodes( tr2, aNodes2, 3 );
- return true;
+ //MESSAGE( tr1 << tr2 );
+
+ return true;
+ }
+ // check case of quadratic faces
+ const SMDS_QuadraticFaceOfNodes* QF1 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
+ if(!QF1) return false;
+ const SMDS_QuadraticFaceOfNodes* QF2 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
+ if(!QF2) return false;
+ return InverseDiag(tr1,tr2);
}
//=======================================================================
const SMDS_MeshElement * tr1,
const SMDS_MeshElement * tr2 )
{
+ if( tr1->NbNodes() != tr2->NbNodes() )
+ return false;
// find the 4-th node to insert into tr1
const SMDS_MeshNode* n4 = 0;
SMDS_ElemIteratorPtr it = tr2->nodesIterator();
- while ( !n4 && it->more() )
- {
+ int i=0;
+ //while ( !n4 && it->more() ) {
+ while ( !n4 && i<3 ) {
const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+ i++;
bool isDiag = ( n == theNode1 || n == theNode2 );
if ( !isDiag )
n4 = n;
// Make an array of nodes to be in a quadrangle
int iNode = 0, iFirstDiag = -1;
it = tr1->nodesIterator();
- while ( it->more() )
- {
+ i=0;
+ //while ( it->more() ) {
+ while ( i<3 ) {
const SMDS_MeshNode * n = static_cast<const SMDS_MeshNode*>( it->next() );
+ i++;
bool isDiag = ( n == theNode1 || n == theNode2 );
- if ( isDiag )
- {
+ if ( isDiag ) {
if ( iFirstDiag < 0 )
iFirstDiag = iNode;
else if ( iNode - iFirstDiag == 1 )
theQuadNodes[ iNode++ ] = n4; // insert the 4-th node between diagonal nodes
}
- else if ( n == n4 )
- {
+ else if ( n == n4 ) {
return false; // tr1 and tr2 should not have all the same nodes
}
theQuadNodes[ iNode++ ] = n;
return false;
const SMDS_FaceOfNodes* F1 = dynamic_cast<const SMDS_FaceOfNodes*>( tr1 );
- if (!F1) return false;
+ //if (!F1) return false;
const SMDS_FaceOfNodes* F2 = dynamic_cast<const SMDS_FaceOfNodes*>( tr2 );
- if (!F2) return false;
+ //if (!F2) return false;
+ if (F1 && F2) {
- const SMDS_MeshNode* aNodes [ 4 ];
- if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
- return false;
+ const SMDS_MeshNode* aNodes [ 4 ];
+ if ( ! getQuadrangleNodes( aNodes, theNode1, theNode2, tr1, tr2 ))
+ return false;
+
+ //MESSAGE( endl << tr1 << tr2 );
+
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+ GetMeshDS()->RemoveElement( tr2 );
- //MESSAGE( endl << tr1 << tr2 );
+ //MESSAGE( endl << tr1 );
- GetMeshDS()->ChangeElementNodes( tr1, aNodes, 4 );
+ return true;
+ }
+
+ // check case of quadratic faces
+ const SMDS_QuadraticFaceOfNodes* QF1 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr1);
+ if(!QF1) return false;
+ const SMDS_QuadraticFaceOfNodes* QF2 =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (tr2);
+ if(!QF2) return false;
+
+ // 5
+ // 1 +--+--+ 2 tr1: (1 2 4 5 9 7) or (2 4 1 9 7 5) or (4 1 2 7 5 9)
+ // | /| tr2: (2 3 4 6 8 9) or (3 4 2 8 9 6) or (4 2 3 9 6 8)
+ // | / |
+ // 7 + + + 6
+ // | /9 |
+ // |/ |
+ // 4 +--+--+ 3
+ // 8
+
+ const SMDS_MeshNode* N1 [6];
+ const SMDS_MeshNode* N2 [6];
+ if(!GetNodesFromTwoTria(tr1,tr2,N1,N2))
+ return false;
+ // now we receive following N1 and N2 (using numeration as above image)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // i.e. first nodes from both arrays determ new diagonal
+
+ const SMDS_MeshNode* aNodes[8];
+ aNodes[0] = N1[0];
+ aNodes[1] = N1[1];
+ aNodes[2] = N2[0];
+ aNodes[3] = N2[1];
+ aNodes[4] = N1[3];
+ aNodes[5] = N2[5];
+ aNodes[6] = N2[3];
+ aNodes[7] = N1[5];
+
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
GetMeshDS()->RemoveElement( tr2 );
- //MESSAGE( endl << tr1 );
+ // remove middle node (9)
+ GetMeshDS()->RemoveNode( N1[4] );
return true;
}
switch ( theElem->GetType() ) {
case SMDSAbs_Edge:
- case SMDSAbs_Face:
- {
- int i = theElem->NbNodes();
- vector<const SMDS_MeshNode*> aNodes( i );
- while ( it->more() )
- aNodes[ --i ]= static_cast<const SMDS_MeshNode*>( it->next() );
- return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() );
+ case SMDSAbs_Face: {
+ if(!theElem->IsQuadratic()) {
+ int i = theElem->NbNodes();
+ vector<const SMDS_MeshNode*> aNodes( i );
+ while ( it->more() )
+ aNodes[ --i ]= static_cast<const SMDS_MeshNode*>( it->next() );
+ return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], theElem->NbNodes() );
+ }
+ else {
+ // quadratic elements
+ if(theElem->GetType()==SMDSAbs_Edge) {
+ vector<const SMDS_MeshNode*> aNodes(3);
+ aNodes[1]= static_cast<const SMDS_MeshNode*>( it->next() );
+ aNodes[0]= static_cast<const SMDS_MeshNode*>( it->next() );
+ aNodes[2]= static_cast<const SMDS_MeshNode*>( it->next() );
+ return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], 3 );
+ }
+ else {
+ int nbn = theElem->NbNodes();
+ vector<const SMDS_MeshNode*> aNodes(nbn);
+ aNodes[0]= static_cast<const SMDS_MeshNode*>( it->next() );
+ int i=1;
+ for(; i<nbn/2; i++) {
+ aNodes[nbn/2-i]= static_cast<const SMDS_MeshNode*>( it->next() );
+ }
+ for(i=0; i<nbn/2; i++) {
+ aNodes[nbn-i-1]= static_cast<const SMDS_MeshNode*>( it->next() );
+ }
+ return GetMeshDS()->ChangeElementNodes( theElem, &aNodes[0], nbn );
+ }
+ }
}
- case SMDSAbs_Volume:
- {
+ case SMDSAbs_Volume: {
if (theElem->IsPoly()) {
const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
for (int iface = 1; iface <= nbFaces; iface++) {
int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
quantities[iface - 1] = nbFaceNodes;
-
+
for (inode = nbFaceNodes; inode >= 1; inode--) {
const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
poly_nodes.push_back(curNode);
}
}
-
+
return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
- } else {
+ }
+ else {
SMDS_VolumeTool vTool;
if ( !vTool.Set( theElem ))
return false;
SMESHDS_Mesh * aMesh = GetMeshDS();
set< const SMDS_MeshElement * >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
- if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 )
+ if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
- // retrieve element nodes
- const SMDS_MeshNode* aNodes [4];
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- int i = 0;
- while ( itN->more() )
- aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
-
- // compare two sets of possible triangles
- double aBadRate1, aBadRate2; // to what extent a set is bad
- SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
- SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
- aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+ if(elem->NbNodes()==4) {
- SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
- SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
- aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+ // retrieve element nodes
+ const SMDS_MeshNode* aNodes [4];
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int i = 0;
+ while ( itN->more() )
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+
+ // compare two sets of possible triangles
+ double aBadRate1, aBadRate2; // to what extent a set is bad
+ SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+ SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+ aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+
+ SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+ SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+ aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
- int aShapeId = FindShape( elem );
- //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
+ int aShapeId = FindShape( elem );
+ //MESSAGE( "aBadRate1 = " << aBadRate1 << "; aBadRate2 = " << aBadRate2
// << " ShapeID = " << aShapeId << endl << elem );
- if ( aBadRate1 <= aBadRate2 ) {
- // tr1 + tr2 is better
- aMesh->ChangeElementNodes( elem, aNodes, 3 );
+ if ( aBadRate1 <= aBadRate2 ) {
+ // tr1 + tr2 is better
+ aMesh->ChangeElementNodes( elem, aNodes, 3 );
+ //MESSAGE( endl << elem );
+
+ elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+ }
+ else {
+ // tr3 + tr4 is better
+ aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
+ //MESSAGE( endl << elem );
+
+ elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+ }
//MESSAGE( endl << elem );
- elem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+ // put a new triangle on the same shape
+ if ( aShapeId )
+ aMesh->SetMeshElementOnShape( elem, aShapeId );
}
- else {
- // tr3 + tr4 is better
- aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
- //MESSAGE( endl << elem );
- elem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+ if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
+ const SMDS_MeshNode* aNodes [8];
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int i = 0;
+ while ( itN->more() ) {
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ }
+
+ // compare two sets of possible triangles
+ // use for comparing simple triangles (not quadratic)
+ double aBadRate1, aBadRate2; // to what extent a set is bad
+ SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+ SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+ aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+
+ SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+ SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+ aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+
+ int aShapeId = FindShape( elem );
+
+ // find middle point for (0,1,2,3)
+ // and create node in this point;
+ double x=0., y=0., z=0.;
+ for(i=0; i<4; i++) {
+ x += aNodes[i]->X();
+ y += aNodes[i]->Y();
+ z += aNodes[i]->Z();
+ }
+ const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
+
+ if ( aBadRate1 <= aBadRate2 ) {
+ // tr1 + tr2 is better
+ const SMDS_MeshNode* N[6];
+ N[0] = aNodes[0];
+ N[1] = aNodes[1];
+ N[2] = aNodes[2];
+ N[3] = aNodes[4];
+ N[4] = aNodes[5];
+ N[5] = newN;
+ aMesh->ChangeElementNodes( elem, N, 6 );
+ elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+ aNodes[6], aNodes[7], newN );
+ }
+ else {
+ // tr3 + tr4 is better
+ const SMDS_MeshNode* N[6];
+ N[0] = aNodes[1];
+ N[1] = aNodes[2];
+ N[2] = aNodes[3];
+ N[3] = aNodes[5];
+ N[4] = aNodes[6];
+ N[5] = newN;
+ aMesh->ChangeElementNodes( elem, N, 6 );
+ elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+ aNodes[7], aNodes[4], newN );
+ }
+ // put a new triangle on the same shape
+ if ( aShapeId ) {
+ aMesh->SetMeshElementOnShape( elem, aShapeId );
+ }
}
- //MESSAGE( endl << elem );
- // put a new triangle on the same shape
- if ( aShapeId )
- aMesh->SetMeshElementOnShape( elem, aShapeId );
}
-
return true;
}
if (!theCrit.get())
return -1;
- if (!theQuad || theQuad->GetType() != SMDSAbs_Face || theQuad->NbNodes() != 4)
+ if (!theQuad || theQuad->GetType() != SMDSAbs_Face )
return -1;
- // retrieve element nodes
- const SMDS_MeshNode* aNodes [4];
- SMDS_ElemIteratorPtr itN = theQuad->nodesIterator();
- int i = 0;
- while (itN->more())
- aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if( theQuad->NbNodes()==4 ||
+ (theQuad->NbNodes()==8 && theQuad->IsQuadratic()) ) {
- // compare two sets of possible triangles
- double aBadRate1, aBadRate2; // to what extent a set is bad
- SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
- SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
- aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
+ // retrieve element nodes
+ const SMDS_MeshNode* aNodes [4];
+ SMDS_ElemIteratorPtr itN = theQuad->nodesIterator();
+ int i = 0;
+ //while (itN->more())
+ while (i<4) {
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ }
+ // compare two sets of possible triangles
+ double aBadRate1, aBadRate2; // to what extent a set is bad
+ SMDS_FaceOfNodes tr1 ( aNodes[0], aNodes[1], aNodes[2] );
+ SMDS_FaceOfNodes tr2 ( aNodes[2], aNodes[3], aNodes[0] );
+ aBadRate1 = getBadRate( &tr1, theCrit ) + getBadRate( &tr2, theCrit );
- SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
- SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
- aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
+ SMDS_FaceOfNodes tr3 ( aNodes[1], aNodes[2], aNodes[3] );
+ SMDS_FaceOfNodes tr4 ( aNodes[3], aNodes[0], aNodes[1] );
+ aBadRate2 = getBadRate( &tr3, theCrit ) + getBadRate( &tr4, theCrit );
- if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
- return 1; // diagonal 1-3
+ if (aBadRate1 <= aBadRate2) // tr1 + tr2 is better
+ return 1; // diagonal 1-3
- return 2; // diagonal 2-4
+ return 2; // diagonal 2-4
+ }
+ return -1;
}
//=======================================================================
SMESHDS_Mesh * aMesh = GetMeshDS();
set< const SMDS_MeshElement * >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
- if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() != 4 )
+ if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
+ bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
+ if(!isquad) continue;
- // retrieve element nodes
- const SMDS_MeshNode* aNodes [4];
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- int i = 0;
- while ( itN->more() )
- aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if(elem->NbNodes()==4) {
+ // retrieve element nodes
+ const SMDS_MeshNode* aNodes [4];
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int i = 0;
+ while ( itN->more() )
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
- int aShapeId = FindShape( elem );
- const SMDS_MeshElement* newElem = 0;
- if ( the13Diag )
- {
- aMesh->ChangeElementNodes( elem, aNodes, 3 );
- newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
- }
- else
- {
- aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
- newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+ int aShapeId = FindShape( elem );
+ const SMDS_MeshElement* newElem = 0;
+ if ( the13Diag ) {
+ aMesh->ChangeElementNodes( elem, aNodes, 3 );
+ newElem = aMesh->AddFace( aNodes[2], aNodes[3], aNodes[0] );
+ }
+ else {
+ aMesh->ChangeElementNodes( elem, &aNodes[1], 3 );
+ newElem = aMesh->AddFace( aNodes[3], aNodes[0], aNodes[1] );
+ }
+ // put a new triangle on the same shape and add to the same groups
+ if ( aShapeId )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ AddToSameGroups( newElem, elem, aMesh );
}
- // put a new triangle on the same shape and add to the same groups
+ if( elem->NbNodes()==8 && elem->IsQuadratic() ) {
+ const SMDS_MeshNode* aNodes [8];
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int i = 0;
+ while ( itN->more() ) {
+ aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ }
- if ( aShapeId )
- aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ // find middle point for (0,1,2,3)
+ // and create node in this point;
+ double x=0., y=0., z=0.;
+ for(i=0; i<4; i++) {
+ x += aNodes[i]->X();
+ y += aNodes[i]->Y();
+ z += aNodes[i]->Z();
+ }
+ const SMDS_MeshNode* newN = aMesh->AddNode(x/4, y/4, z/4);
- AddToSameGroups( newElem, elem, aMesh );
+ int aShapeId = FindShape( elem );
+ const SMDS_MeshElement* newElem = 0;
+ if ( the13Diag ) {
+ const SMDS_MeshNode* N[6];
+ N[0] = aNodes[0];
+ N[1] = aNodes[1];
+ N[2] = aNodes[2];
+ N[3] = aNodes[4];
+ N[4] = aNodes[5];
+ N[5] = newN;
+ aMesh->ChangeElementNodes( elem, N, 6 );
+ elem = aMesh->AddFace(aNodes[2], aNodes[3], aNodes[0],
+ aNodes[6], aNodes[7], newN );
+ }
+ else {
+ const SMDS_MeshNode* N[6];
+ N[0] = aNodes[1];
+ N[1] = aNodes[2];
+ N[2] = aNodes[3];
+ N[3] = aNodes[5];
+ N[4] = aNodes[6];
+ N[5] = newN;
+ aMesh->ChangeElementNodes( elem, N, 6 );
+ elem = aMesh->AddFace(aNodes[3], aNodes[0], aNodes[1],
+ aNodes[7], aNodes[4], newN );
+ }
+ // put a new triangle on the same shape and add to the same groups
+ if ( aShapeId )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ AddToSameGroups( newElem, elem, aMesh );
+ }
}
return true;
if ( !SMESH::Controls::NumericalFunctor::GetPoints( tr1, P1 ) ||
!SMESH::Controls::NumericalFunctor::GetPoints( tr2, P2 ))
return angle;
- gp_Vec N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) );
+ gp_Vec N1,N2;
+ if(!tr1->IsQuadratic())
+ N1 = gp_Vec( P1(2) - P1(1) ) ^ gp_Vec( P1(3) - P1(1) );
+ else
+ N1 = gp_Vec( P1(3) - P1(1) ) ^ gp_Vec( P1(5) - P1(1) );
if ( N1.SquareMagnitude() <= gp::Resolution() )
return angle;
- gp_Vec N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
+ if(!tr2->IsQuadratic())
+ N2 = gp_Vec( P2(2) - P2(1) ) ^ gp_Vec( P2(3) - P2(1) );
+ else
+ N2 = gp_Vec( P2(3) - P2(1) ) ^ gp_Vec( P2(5) - P2(1) );
if ( N2.SquareMagnitude() <= gp::Resolution() )
return angle;
// find the first diagonal node n1 in the triangles:
// take in account a diagonal link orientation
const SMDS_MeshElement *nFirst[2], *tr[] = { tr1, tr2 };
- for ( int t = 0; t < 2; t++ )
- {
+ for ( int t = 0; t < 2; t++ ) {
SMDS_ElemIteratorPtr it = tr[ t ]->nodesIterator();
int i = 0, iDiag = -1;
while ( it->more()) {
// class generating a unique ID for a pair of nodes
// and able to return nodes by that ID
// =================================================
-
class LinkID_Gen {
public:
long myMaxID;
};
+
//=======================================================================
//function : TriToQuad
//purpose : Fuse neighbour triangles into quadrangles.
return false;
SMESHDS_Mesh * aMesh = GetMeshDS();
- LinkID_Gen aLinkID_Gen( aMesh );
-
+ //LinkID_Gen aLinkID_Gen( aMesh );
// Prepare data for algo: build
// 1. map of elements with their linkIDs
// 2. map of linkIDs with their elements
- map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
- map< long, list< const SMDS_MeshElement* > >::iterator itLE;
- map< const SMDS_MeshElement*, set< long > > mapEl_setLi;
- map< const SMDS_MeshElement*, set< long > >::iterator itEL;
+ //map< long, list< const SMDS_MeshElement* > > mapLi_listEl;
+ //map< long, list< const SMDS_MeshElement* > >::iterator itLE;
+ //map< const SMDS_MeshElement*, set< long > > mapEl_setLi;
+ //map< const SMDS_MeshElement*, set< long > >::iterator itEL;
+
+ map< NLink, list< const SMDS_MeshElement* > > mapLi_listEl;
+ map< NLink, list< const SMDS_MeshElement* > >::iterator itLE;
+ map< const SMDS_MeshElement*, set< NLink > > mapEl_setLi;
+ map< const SMDS_MeshElement*, set< NLink > >::iterator itEL;
set<const SMDS_MeshElement*>::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
- if ( !elem || elem->NbNodes() != 3 )
- continue;
+ //if ( !elem || elem->NbNodes() != 3 )
+ // continue;
+ if(!elem || elem->GetType() != SMDSAbs_Face ) continue;
+ bool IsTria = elem->NbNodes()==3 || (elem->NbNodes()==6 && elem->IsQuadratic());
+ if(!IsTria) continue;
// retrieve element nodes
const SMDS_MeshNode* aNodes [4];
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0;
- while ( itN->more() )
+ //while ( itN->more() )
+ while ( i<3 )
aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
ASSERT( i == 3 );
aNodes[ 3 ] = aNodes[ 0 ];
// fill maps
- for ( i = 0; i < 3; i++ )
- {
- long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
+ for ( i = 0; i < 3; i++ ) {
+ //long linkID = aLinkID_Gen.GetLinkID( aNodes[ i ], aNodes[ i+1 ] );
+ NLink link(( aNodes[i] < aNodes[i+1] ? aNodes[i] : aNodes[i+1] ),
+ ( aNodes[i] < aNodes[i+1] ? aNodes[i+1] : aNodes[i] ));
// check if elements sharing a link can be fused
- itLE = mapLi_listEl.find( linkID );
- if ( itLE != mapLi_listEl.end() )
- {
+ //itLE = mapLi_listEl.find( linkID );
+ itLE = mapLi_listEl.find( link );
+ if ( itLE != mapLi_listEl.end() ) {
if ((*itLE).second.size() > 1 ) // consider only 2 elems adjacent by a link
continue;
const SMDS_MeshElement* elem2 = (*itLE).second.front();
-// if ( FindShape( elem ) != FindShape( elem2 ))
-// continue; // do not fuse triangles laying on different shapes
+ //if ( FindShape( elem ) != FindShape( elem2 ))
+ // continue; // do not fuse triangles laying on different shapes
if ( getAngle( elem, elem2, aNodes[i], aNodes[i+1] ) > theMaxAngle )
continue; // avoid making badly shaped quads
(*itLE).second.push_back( elem );
}
- else
- mapLi_listEl[ linkID ].push_back( elem );
- mapEl_setLi [ elem ].insert( linkID );
+ else {
+ //mapLi_listEl[ linkID ].push_back( elem );
+ mapLi_listEl[ link ].push_back( elem );
+ }
+ //mapEl_setLi [ elem ].insert( linkID );
+ mapEl_setLi [ elem ].insert( link );
}
}
// Clean the maps from the links shared by a sole element, ie
// links to which only one element is bound in mapLi_listEl
- for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ )
- {
+ for ( itLE = mapLi_listEl.begin(); itLE != mapLi_listEl.end(); itLE++ ) {
int nbElems = (*itLE).second.size();
if ( nbElems < 2 ) {
const SMDS_MeshElement* elem = (*itLE).second.front();
- long link = (*itLE).first;
+ //long link = (*itLE).first;
+ NLink link = (*itLE).first;
mapEl_setLi[ elem ].erase( link );
if ( mapEl_setLi[ elem ].empty() )
mapEl_setLi.erase( elem );
// Algo: fuse triangles into quadrangles
- while ( ! mapEl_setLi.empty() )
- {
+ while ( ! mapEl_setLi.empty() ) {
// Look for the start element:
// the element having the least nb of shared links
const SMDS_MeshElement* startElem = 0;
int minNbLinks = 4;
- for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ )
- {
+ for ( itEL = mapEl_setLi.begin(); itEL != mapEl_setLi.end(); itEL++ ) {
int nbLinks = (*itEL).second.size();
- if ( nbLinks < minNbLinks )
- {
+ if ( nbLinks < minNbLinks ) {
startElem = (*itEL).first;
minNbLinks = nbLinks;
if ( minNbLinks == 1 )
// search elements to fuse starting from startElem or links of elements
// fused earlyer - startLinks
- list< long > startLinks;
- while ( startElem || !startLinks.empty() )
- {
- while ( !startElem && !startLinks.empty() )
- {
+ //list< long > startLinks;
+ list< NLink > startLinks;
+ while ( startElem || !startLinks.empty() ) {
+ while ( !startElem && !startLinks.empty() ) {
// Get an element to start, by a link
- long linkId = startLinks.front();
+ //long linkId = startLinks.front();
+ NLink linkId = startLinks.front();
startLinks.pop_front();
itLE = mapLi_listEl.find( linkId );
- if ( itLE != mapLi_listEl.end() )
- {
+ if ( itLE != mapLi_listEl.end() ) {
list< const SMDS_MeshElement* > & listElem = (*itLE).second;
list< const SMDS_MeshElement* >::iterator itE = listElem.begin();
for ( ; itE != listElem.end() ; itE++ )
}
}
- if ( startElem )
- {
+ if ( startElem ) {
// Get candidates to be fused
-
const SMDS_MeshElement *tr1 = startElem, *tr2 = 0, *tr3 = 0;
- long link12, link13;
+ //long link12, link13;
+ NLink link12, link13;
startElem = 0;
ASSERT( mapEl_setLi.find( tr1 ) != mapEl_setLi.end() );
- set< long >& setLi = mapEl_setLi[ tr1 ];
+ //set< long >& setLi = mapEl_setLi[ tr1 ];
+ set< NLink >& setLi = mapEl_setLi[ tr1 ];
ASSERT( !setLi.empty() );
- set< long >::iterator itLi;
- for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ )
- {
- long linkID = (*itLi);
+ //set< long >::iterator itLi;
+ set< NLink >::iterator itLi;
+ for ( itLi = setLi.begin(); itLi != setLi.end(); itLi++ ) {
+ //long linkID = (*itLi);
+ NLink linkID = (*itLi);
itLE = mapLi_listEl.find( linkID );
if ( itLE == mapLi_listEl.end() )
continue;
+
const SMDS_MeshElement* elem = (*itLE).second.front();
if ( elem == tr1 )
elem = (*itLE).second.back();
mapLi_listEl.erase( itLE );
if ( mapEl_setLi.find( elem ) == mapEl_setLi.end())
continue;
- if ( tr2 )
- {
+ if ( tr2 ) {
tr3 = elem;
link13 = linkID;
}
- else
- {
+ else {
tr2 = elem;
link12 = linkID;
}
// add other links of elem to list of links to re-start from
- set< long >& links = mapEl_setLi[ elem ];
- set< long >::iterator it;
- for ( it = links.begin(); it != links.end(); it++ )
- {
- long linkID2 = (*it);
+ //set< long >& links = mapEl_setLi[ elem ];
+ //set< long >::iterator it;
+ set< NLink >& links = mapEl_setLi[ elem ];
+ set< NLink >::iterator it;
+ for ( it = links.begin(); it != links.end(); it++ ) {
+ //long linkID2 = (*it);
+ NLink linkID2 = (*it);
if ( linkID2 != linkID )
startLinks.push_back( linkID2 );
}
}
// Get nodes of possible quadrangles
-
const SMDS_MeshNode *n12 [4], *n13 [4];
bool Ok12 = false, Ok13 = false;
+ //const SMDS_MeshNode *linkNode1, *linkNode2;
const SMDS_MeshNode *linkNode1, *linkNode2;
- if ( tr2 &&
- aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
- getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
- Ok12 = true;
- if ( tr3 &&
- aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
- getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
- Ok13 = true;
+ if(tr2) {
+ //const SMDS_MeshNode *linkNode1 = link12.first;
+ //const SMDS_MeshNode *linkNode2 = link12.second;
+ linkNode1 = link12.first;
+ linkNode2 = link12.second;
+ //if ( tr2 &&
+ // aLinkID_Gen.GetNodes( link12, linkNode1, linkNode2 ) &&
+ // getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
+ // Ok12 = true;
+ if ( tr2 && getQuadrangleNodes( n12, linkNode1, linkNode2, tr1, tr2 ))
+ Ok12 = true;
+ }
+ if(tr3) {
+ linkNode1 = link13.first;
+ linkNode2 = link13.second;
+ //if ( tr3 &&
+ // aLinkID_Gen.GetNodes( link13, linkNode1, linkNode2 ) &&
+ // getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
+ // Ok13 = true;
+ if ( tr3 && getQuadrangleNodes( n13, linkNode1, linkNode2, tr1, tr3 ))
+ Ok13 = true;
+ }
// Choose a pair to fuse
-
- if ( Ok12 && Ok13 )
- {
+ if ( Ok12 && Ok13 ) {
SMDS_FaceOfNodes quad12 ( n12[ 0 ], n12[ 1 ], n12[ 2 ], n12[ 3 ] );
SMDS_FaceOfNodes quad13 ( n13[ 0 ], n13[ 1 ], n13[ 2 ], n13[ 3 ] );
double aBadRate12 = getBadRate( &quad12, theCrit );
Ok13 = false;
}
-
// Make quadrangles
// and remove fused elems and removed links from the maps
-
mapEl_setLi.erase( tr1 );
- if ( Ok12 )
- {
+ if ( Ok12 ) {
mapEl_setLi.erase( tr2 );
mapLi_listEl.erase( link12 );
- aMesh->ChangeElementNodes( tr1, n12, 4 );
- aMesh->RemoveElement( tr2 );
+ if(tr1->NbNodes()==3) {
+ aMesh->ChangeElementNodes( tr1, n12, 4 );
+ aMesh->RemoveElement( tr2 );
+ }
+ else {
+ const SMDS_MeshNode* N1 [6];
+ const SMDS_MeshNode* N2 [6];
+ GetNodesFromTwoTria(tr1,tr2,N1,N2);
+ // now we receive following N1 and N2 (using numeration as above image)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // i.e. first nodes from both arrays determ new diagonal
+ const SMDS_MeshNode* aNodes[8];
+ aNodes[0] = N1[0];
+ aNodes[1] = N1[1];
+ aNodes[2] = N2[0];
+ aNodes[3] = N2[1];
+ aNodes[4] = N1[3];
+ aNodes[5] = N2[5];
+ aNodes[6] = N2[3];
+ aNodes[7] = N1[5];
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+ GetMeshDS()->RemoveElement( tr2 );
+ // remove middle node (9)
+ GetMeshDS()->RemoveNode( N1[4] );
+ }
}
- else if ( Ok13 )
- {
+ else if ( Ok13 ) {
mapEl_setLi.erase( tr3 );
mapLi_listEl.erase( link13 );
- aMesh->ChangeElementNodes( tr1, n13, 4 );
- aMesh->RemoveElement( tr3 );
+ if(tr1->NbNodes()==3) {
+ aMesh->ChangeElementNodes( tr1, n13, 4 );
+ aMesh->RemoveElement( tr3 );
+ }
+ else {
+ const SMDS_MeshNode* N1 [6];
+ const SMDS_MeshNode* N2 [6];
+ GetNodesFromTwoTria(tr1,tr3,N1,N2);
+ // now we receive following N1 and N2 (using numeration as above image)
+ // tria1 : (1 2 4 5 9 7) and tria2 : (3 4 2 8 9 6)
+ // i.e. first nodes from both arrays determ new diagonal
+ const SMDS_MeshNode* aNodes[8];
+ aNodes[0] = N1[0];
+ aNodes[1] = N1[1];
+ aNodes[2] = N2[0];
+ aNodes[3] = N2[1];
+ aNodes[4] = N1[3];
+ aNodes[5] = N2[5];
+ aNodes[6] = N2[3];
+ aNodes[7] = N1[5];
+ GetMeshDS()->ChangeElementNodes( tr1, aNodes, 8 );
+ GetMeshDS()->RemoveElement( tr3 );
+ // remove middle node (9)
+ GetMeshDS()->RemoveNode( N1[4] );
+ }
}
// Next element to fuse: the rejected one
// put all nodes in array
int nbNodes = 0, iNode = 0;
vector< const SMDS_MeshNode*> aNodes( elem->NbNodes() );
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
- {
- aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
- if ( aNodes[ nbNodes ] == theNode )
- iNode = nbNodes; // index of theNode within aNodes
- nbNodes++;
+ if(!elem->IsQuadratic()) {
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( aNodes[ nbNodes ] == theNode )
+ iNode = nbNodes; // index of theNode within aNodes
+ nbNodes++;
+ }
+ }
+ else {
+ int nbn = elem->NbNodes()/2;
+ aNodes.resize(nbn);
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while ( nbNodes<nbn ) {
+ aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( aNodes[ nbNodes ] == theNode )
+ iNode = nbNodes; // index of theNode within aNodes
+ nbNodes++;
+ }
}
// add linked nodes
int iAfter = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
gp_XYZ elemCenter(0.,0.,0.);
SMESH::Controls::TSequenceOfXYZ aNodePoints;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
- {
+ int nn = elem->NbNodes();
+ if(elem->IsQuadratic()) nn = nn/2;
+ int i=0;
+ //while ( itN->more() ) {
+ while ( i<nn ) {
const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( itN->next() );
+ i++;
gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
aNodePoints.push_back( aP );
if ( !theSurface.IsNull() ) { // smooth in 2D
if ( theTgtAspectRatio < 1.0 )
theTgtAspectRatio = 1.0;
+ double disttol = 1.e-16;
+
SMESH::Controls::AspectRatio aQualityFunc;
SMESHDS_Mesh* aMesh = GetMeshDS();
// smooth elements on each TopoDS_Face separately
// ===============================================
+ set<const SMDS_MeshElement*> QuadElems;
+
set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end
- for ( ; fId != faceIdSet.rend(); ++fId )
- {
+ for ( ; fId != faceIdSet.rend(); ++fId ) {
// get face surface and submesh
Handle(Geom_Surface) surface;
SMESHDS_SubMesh* faceSubMesh = 0;
int nbElemOnFace = 0;
itElem = theElems.begin();
// loop on not yet smoothed elements: look for elems on a face
- while ( itElem != theElems.end() )
- {
+ while ( itElem != theElems.end() ) {
if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
break; // all elements found
continue;
}
elemsOnFace.push_back( elem );
+ if(elem->IsQuadratic()) {
+ QuadElems.insert(elem);
+ }
theElems.erase( itElem++ );
nbElemOnFace++;
const SMDS_MeshNode* node;
SMDS_TypeOfPosition posType;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
+ int nbn = elem->NbNodes();
+ if(elem->IsQuadratic())
+ nbn = nbn/2;
+ int nn = 0;
+ //while ( itN->more() ) {
+ while ( nn<nbn ) {
+ nn++;
node = static_cast<const SMDS_MeshNode*>( itN->next() );
const SMDS_PositionPtr& pos = node->GetPosition();
posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
}
// check UV on face
list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
- for ( ; n != uvCheckNodes.end(); ++n )
- {
+ for ( ; n != uvCheckNodes.end(); ++n ) {
node = *n;
gp_XY uv( 0, 0 );
const SMDS_PositionPtr& pos = node->GetPosition();
// fix nodes on mesh boundary
- if ( checkBoundaryNodes )
- {
+ if ( checkBoundaryNodes ) {
typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
map< TLink, int >::iterator link_nb;
// put all elements links to linkNbMap
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
- for ( ; elemIt != elemsOnFace.end(); ++elemIt )
- {
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
+ const SMDS_MeshElement* elem = (*elemIt);
// put elem nodes in array
vector< const SMDS_MeshNode* > nodes;
- nodes.reserve( (*elemIt)->NbNodes() + 1 );
- SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator();
- while ( itN->more() )
- nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+ if(!elem->IsQuadratic()) {
+ nodes.reserve( elem->NbNodes() + 1 );
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while ( itN->more() )
+ nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+ }
+ else {
+ nodes.reserve( elem->NbNodes()/2 + 1 );
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ int nbn = 0;
+ while ( nbn<elem->NbNodes()/2 ) {
+ nbn++;
+ nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+ }
+ }
nodes.push_back( nodes.front() );
// loop on elem links: insert them in linkNbMap
for ( int iN = 1; iN < nodes.size(); ++iN ) {
// -----------------------------------------------------
set<const SMDS_MeshNode*> nodesNearSeam; // to smooth using uvMap2
- if ( !surface.IsNull() )
- {
+ if ( !surface.IsNull() ) {
TopExp_Explorer eExp( face, TopAbs_EDGE );
- for ( ; eExp.More(); eExp.Next() )
- {
+ for ( ; eExp.More(); eExp.Next() ) {
TopoDS_Edge edge = TopoDS::Edge( eExp.Current() );
if ( !BRep_Tool::IsClosed( edge, face ))
continue;
}
// loop on nodes on seam
list< const SMDS_MeshNode* >::iterator noSeIt = seamNodes.begin();
- for ( ; noSeIt != seamNodes.end(); ++noSeIt )
- {
+ for ( ; noSeIt != seamNodes.end(); ++noSeIt ) {
const SMDS_MeshNode* nSeam = *noSeIt;
map< const SMDS_MeshNode*, gp_XY* >::iterator n_uv = uvMap.find( nSeam );
if ( n_uv == uvMap.end() )
// collect movable nodes linked to ones on seam in nodesNearSeam
SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator();
- while ( eIt->more() )
- {
+ while ( eIt->more() ) {
const SMDS_MeshElement* e = eIt->next();
if ( e->GetType() != SMDSAbs_Face )
continue;
}
// for centroidalSmooth all element nodes must
// be on one side of a seam
- if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 )
- {
+ if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 ) {
SMDS_ElemIteratorPtr nIt = e->nodesIterator();
while ( nIt->more() ) {
const SMDS_MeshNode* n =
int it = -1;
double maxRatio = -1., maxDisplacement = -1.;
set<const SMDS_MeshNode*>::iterator nodeToMove;
- for ( it = 0; it < theNbIterations; it++ )
- {
+ for ( it = 0; it < theNbIterations; it++ ) {
maxDisplacement = 0.;
nodeToMove = setMovableNodes.begin();
- for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
- {
+ for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) {
const SMDS_MeshNode* node = (*nodeToMove);
gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() );
maxDisplacement = aDispl;
}
// no node movement => exit
- if ( maxDisplacement < 1.e-16 ) {
+ //if ( maxDisplacement < 1.e-16 ) {
+ if ( maxDisplacement < disttol ) {
MESSAGE("-- no node movement --");
break;
}
// check elements quality
maxRatio = 0;
list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
- for ( ; elemIt != elemsOnFace.end(); ++elemIt )
- {
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt ) {
const SMDS_MeshElement* elem = (*elemIt);
if ( !elem || elem->GetType() != SMDSAbs_Face )
continue;
// new nodes positions are computed,
// record movement in DS and set new UV
// ---------------------------------------
-
nodeToMove = setMovableNodes.begin();
- for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
- {
+ for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ ) {
SMDS_MeshNode* node = const_cast< SMDS_MeshNode* > (*nodeToMove);
aMesh->MoveNode( node, node->X(), node->Y(), node->Z() );
map< const SMDS_MeshNode*, gp_XY* >::iterator node_uv = uvMap.find( node );
}
} // loop on face ids
+
+ set< const SMDS_MeshElement* >::iterator itq;
+ for ( itq = QuadElems.begin(); itq != QuadElems.end(); itq++ ) {
+ const SMDS_QuadraticFaceOfNodes* QF =
+ dynamic_cast<const SMDS_QuadraticFaceOfNodes*> (*itq);
+ if(QF) {
+ vector<const SMDS_MeshNode*> Ns(QF->NbNodes()+1);
+ SMDS_NodeIteratorPtr anIter = QF->interlacedNodesIterator();
+ int nn = 0;
+ while( anIter->more() ) {
+ Ns[nn++] = anIter->next();
+ //Ns.push_back(anIter->next());
+ }
+ Ns[nn] = Ns[0];
+ //Ns.push_back(Ns[0]);
+ int i=0;
+ for(; i<QF->NbNodes(); i=i+2) {
+ double x = (Ns[i]->X() + Ns[i+2]->X())/2;
+ double y = (Ns[i]->Y() + Ns[i+2]->Y())/2;
+ double z = (Ns[i]->Z() + Ns[i+2]->Z())/2;
+ if( fabs( Ns[i+1]->X() - x ) > disttol ||
+ fabs( Ns[i+1]->Y() - y ) > disttol ||
+ fabs( Ns[i+1]->Z() - z ) > disttol ) {
+ // we have to move i+1 node
+ const_cast<SMDS_MeshNode*>(Ns[i+1])->setXYZ(x,y,z);
+ aMesh->MoveNode( Ns[i+1], x, y, z );
+ }
+ }
+ }
+ }
+ QuadElems.clear();
+
}
//=======================================================================
static void sweepElement(SMESHDS_Mesh* aMesh,
const SMDS_MeshElement* elem,
const vector<TNodeOfNodeListMapItr> & newNodesItVec,
- list<const SMDS_MeshElement*>& newElems)
+ list<const SMDS_MeshElement*>& newElems,
+ const int nbSteps)
{
// Loop on elem nodes:
// find new nodes and detect same nodes indices
int nbNodes = elem->NbNodes();
list<const SMDS_MeshNode*>::const_iterator itNN[ nbNodes ];
- const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ];
+ const SMDS_MeshNode* prevNod[ nbNodes ], *nextNod[ nbNodes ], *midlNod[ nbNodes ];
int iNode, nbSame = 0, iNotSameNode = 0, iSameNode = 0;
+ vector<int> sames(nbNodes);
- for ( iNode = 0; iNode < nbNodes; iNode++ )
- {
+ bool issimple[nbNodes];
+
+ for ( iNode = 0; iNode < nbNodes; iNode++ ) {
TNodeOfNodeListMapItr nnIt = newNodesItVec[ iNode ];
const SMDS_MeshNode* node = nnIt->first;
const list< const SMDS_MeshNode* > & listNewNodes = nnIt->second;
if ( listNewNodes.empty() )
return;
+ if(listNewNodes.size()==nbSteps) {
+ issimple[iNode] = true;
+ }
+ else {
+ issimple[iNode] = false;
+ }
+
itNN[ iNode ] = listNewNodes.begin();
prevNod[ iNode ] = node;
nextNod[ iNode ] = listNewNodes.front();
+//cout<<"iNode="<<iNode<<endl;
+//cout<<" prevNod[iNode]="<< prevNod[iNode]<<" nextNod[iNode]="<< nextNod[iNode]<<endl;
if ( prevNod[ iNode ] != nextNod [ iNode ])
iNotSameNode = iNode;
else {
iSameNode = iNode;
- nbSame++;
+ //nbSame++;
+ sames[nbSame++] = iNode;
}
}
+//cout<<"1 nbSame="<<nbSame<<endl;
if ( nbSame == nbNodes || nbSame > 2) {
MESSAGE( " Too many same nodes of element " << elem->GetID() );
return;
}
+// if( elem->IsQuadratic() && nbSame>0 ) {
+// MESSAGE( "Can not rotate quadratic element " << elem->GetID() );
+// return;
+// }
+
int iBeforeSame = 0, iAfterSame = 0, iOpposSame = 0;
if ( nbSame > 0 ) {
iBeforeSame = ( iSameNode == 0 ? nbNodes - 1 : iSameNode - 1 );
iOpposSame = ( iSameNode - 2 < 0 ? iSameNode + 2 : iSameNode - 2 );
}
+//if(nbNodes==8)
+//cout<<" prevNod[0]="<< prevNod[0]<<" prevNod[1]="<< prevNod[1]
+// <<" prevNod[2]="<< prevNod[2]<<" prevNod[3]="<< prevNod[4]
+// <<" prevNod[4]="<< prevNod[4]<<" prevNod[5]="<< prevNod[5]
+// <<" prevNod[6]="<< prevNod[6]<<" prevNod[7]="<< prevNod[7]<<endl;
+
// check element orientation
int i0 = 0, i2 = 2;
if ( nbNodes > 2 && !isReverse( prevNod, nextNod, nbNodes, iNotSameNode )) {
}
// make new elements
- int iStep, nbSteps = newNodesItVec[ 0 ]->second.size();
- for (iStep = 0; iStep < nbSteps; iStep++ )
- {
+ int iStep;//, nbSteps = newNodesItVec[ 0 ]->second.size();
+ for (iStep = 0; iStep < nbSteps; iStep++ ) {
// get next nodes
for ( iNode = 0; iNode < nbNodes; iNode++ ) {
- nextNod[ iNode ] = *itNN[ iNode ];
- itNN[ iNode ]++;
+ if(issimple[iNode]) {
+ nextNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ }
+ else {
+ if( elem->GetType()==SMDSAbs_Node ) {
+ // we have to use two nodes
+ midlNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ nextNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ }
+ else if(!elem->IsQuadratic() ||
+ elem->IsQuadratic() && elem->IsMediumNode(prevNod[iNode]) ) {
+ // we have to use each second node
+ itNN[ iNode ]++;
+ nextNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ }
+ else {
+ // we have to use two nodes
+ midlNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ nextNod[ iNode ] = *itNN[ iNode ];
+ itNN[ iNode ]++;
+ }
+ }
}
SMDS_MeshElement* aNewElem = 0;
- switch ( nbNodes )
- {
- case 0:
- return;
- case 1: { // NODE
- if ( nbSame == 0 )
- aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
- break;
- }
- case 2: { // EDGE
-
- if ( nbSame == 0 )
- aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
- nextNod[ 1 ], nextNod[ 0 ] );
- else
- aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
- nextNod[ iNotSameNode ] );
- break;
- }
- case 3: { // TRIANGLE
-
- if ( nbSame == 0 ) // --- pentahedron
- aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
- nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
+ if(!elem->IsPoly()) {
+ switch ( nbNodes ) {
+ case 0:
+ return;
+ case 1: { // NODE
+ if ( nbSame == 0 ) {
+ if(issimple[0])
+ aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
+ else
+ aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ], midlNod[ 0 ] );
+ }
+ break;
+ }
+ case 2: { // EDGE
+ if ( nbSame == 0 )
+ aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+ nextNod[ 1 ], nextNod[ 0 ] );
+ else
+ aNewElem = aMesh->AddFace(prevNod[ 0 ], prevNod[ 1 ],
+ nextNod[ iNotSameNode ] );
+ break;
+ }
- else if ( nbSame == 1 ) // --- pyramid
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
- nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
- nextNod[ iSameNode ]);
+ case 3: { // TRIANGLE or quadratic edge
+ if(elem->GetType() == SMDSAbs_Face) { // TRIANGLE
- else // 2 same nodes: --- tetrahedron
- aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
- nextNod[ iNotSameNode ]);
- break;
- }
- case 4: { // QUADRANGLE
+ if ( nbSame == 0 ) // --- pentahedron
+ aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
+ nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
- if ( nbSame == 0 ) // --- hexahedron
- aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
- nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
+ else if ( nbSame == 1 ) // --- pyramid
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+ nextNod[ iSameNode ]);
- else if ( nbSame == 1 ) // --- pyramid + pentahedron
- {
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
- nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
- nextNod[ iSameNode ]);
- newElems.push_back( aNewElem );
- aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
- prevNod[ iBeforeSame ], nextNod[ iAfterSame ],
- nextNod[ iOpposSame ], nextNod[ iBeforeSame ] );
- }
- else if ( nbSame == 2 ) // pentahedron
- {
- if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
- // iBeforeSame is same too
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
- nextNod[ iOpposSame ], prevNod[ iSameNode ],
- prevNod[ iAfterSame ], nextNod[ iAfterSame ]);
- else
- // iAfterSame is same too
- aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
- nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
- prevNod[ iOpposSame ], nextNod[ iOpposSame ]);
+ else // 2 same nodes: --- tetrahedron
+ aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ],
+ nextNod[ iNotSameNode ]);
+ }
+ else { // quadratic edge
+ if(nbSame==0) { // quadratic quadrangle
+ aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], nextNod[1], prevNod[1],
+ midlNod[0], nextNod[2], midlNod[1], prevNod[2]);
+ }
+ else if(nbSame==1) { // quadratic triangle
+ if(sames[0]==2)
+ return; // medium node on axis
+ else if(sames[0]==0) {
+ aNewElem = aMesh->AddFace(prevNod[0], nextNod[1], prevNod[1],
+ nextNod[2], midlNod[1], prevNod[2]);
+ }
+ else { // sames[0]==1
+ aNewElem = aMesh->AddFace(prevNod[0], nextNod[0], prevNod[1],
+ midlNod[0], nextNod[2], prevNod[2]);
+ }
+ }
+ else
+ return;
+ }
+ break;
+ }
+ case 4: { // QUADRANGLE
+
+ if ( nbSame == 0 ) // --- hexahedron
+ aNewElem = aMesh->AddVolume (prevNod[ i0 ], prevNod[ 1 ], prevNod[ i2 ], prevNod[ 3 ],
+ nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ], nextNod[ 3 ]);
+
+ else if ( nbSame == 1 ) { // --- pyramid + pentahedron
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+ nextNod[ iSameNode ]);
+ newElems.push_back( aNewElem );
+ aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
+ prevNod[ iBeforeSame ], nextNod[ iAfterSame ],
+ nextNod[ iOpposSame ], nextNod[ iBeforeSame ] );
+ }
+ else if ( nbSame == 2 ) { // pentahedron
+ if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
+ // iBeforeSame is same too
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
+ nextNod[ iOpposSame ], prevNod[ iSameNode ],
+ prevNod[ iAfterSame ], nextNod[ iAfterSame ]);
+ else
+ // iAfterSame is same too
+ aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
+ nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ prevNod[ iOpposSame ], nextNod[ iOpposSame ]);
+ }
+ break;
+ }
+ case 6: { // quadratic triangle
+ // create pentahedron with 15 nodes
+ if(i0>0) { // reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[2], prevNod[1],
+ nextNod[0], nextNod[2], nextNod[1],
+ prevNod[5], prevNod[4], prevNod[3],
+ nextNod[5], nextNod[4], nextNod[3],
+ midlNod[0], midlNod[2], midlNod[1]);
+ }
+ else { // not reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2],
+ nextNod[0], nextNod[1], nextNod[2],
+ prevNod[3], prevNod[4], prevNod[5],
+ nextNod[3], nextNod[4], nextNod[5],
+ midlNod[0], midlNod[1], midlNod[2]);
+ }
+ break;
+ }
+ case 8: { // quadratic quadrangle
+ // create hexahedron with 20 nodes
+ if(i0>0) { // reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[3], prevNod[2], prevNod[1],
+ nextNod[0], nextNod[3], nextNod[2], nextNod[1],
+ prevNod[7], prevNod[6], prevNod[5], prevNod[4],
+ nextNod[7], nextNod[6], nextNod[5], nextNod[4],
+ midlNod[0], midlNod[3], midlNod[2], midlNod[1]);
+ }
+ else { // not reversed case
+ aNewElem = aMesh->AddVolume (prevNod[0], prevNod[1], prevNod[2], prevNod[3],
+ nextNod[0], nextNod[1], nextNod[2], nextNod[3],
+ prevNod[4], prevNod[5], prevNod[6], prevNod[7],
+ nextNod[4], nextNod[5], nextNod[6], nextNod[7],
+ midlNod[0], midlNod[1], midlNod[2], midlNod[3]);
+ }
+ break;
+ }
+ default: {
+ // realized for extrusion only
+ //vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
+ //vector<int> quantities (nbNodes + 2);
+
+ //quantities[0] = nbNodes; // bottom of prism
+ //for (int inode = 0; inode < nbNodes; inode++) {
+ // polyedre_nodes[inode] = prevNod[inode];
+ //}
+
+ //quantities[1] = nbNodes; // top of prism
+ //for (int inode = 0; inode < nbNodes; inode++) {
+ // polyedre_nodes[nbNodes + inode] = nextNod[inode];
+ //}
+
+ //for (int iface = 0; iface < nbNodes; iface++) {
+ // quantities[iface + 2] = 4;
+ // int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
+ // polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface];
+ // polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface];
+ // polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface];
+ // polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface];
+ //}
+ //aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
+ break;
+ }
}
- break;
}
- default: {
+
+ if(!aNewElem) {
// realized for extrusion only
vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
vector<int> quantities (nbNodes + 2);
}
aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
}
- }
- if ( aNewElem )
+
+ if ( aNewElem ) {
newElems.push_back( aNewElem );
+ }
// set new prev nodes
for ( iNode = 0; iNode < nbNodes; iNode++ )
TNodeOfNodeListMap & mapNewNodes,
TElemOfElemListMap & newElemsMap,
TElemOfVecOfNnlmiMap & elemNewNodesMap,
- set<const SMDS_MeshElement*>& elemSet)
+ set<const SMDS_MeshElement*>& elemSet,
+ const int nbSteps)
{
ASSERT( newElemsMap.size() == elemNewNodesMap.size() );
// Find nodes belonging to only one initial element - sweep them to get edges.
TNodeOfNodeListMapItr nList = mapNewNodes.begin();
- for ( ; nList != mapNewNodes.end(); nList++ )
- {
+ for ( ; nList != mapNewNodes.end(); nList++ ) {
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( nList->first );
SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
int nbInitElems = 0;
- while ( eIt->more() && nbInitElems < 2 )
- if ( elemSet.find( eIt->next() ) != elemSet.end() )
+ const SMDS_MeshElement* el;
+ while ( eIt->more() && nbInitElems < 2 ) {
+ el = eIt->next();
+ //if ( elemSet.find( eIt->next() ) != elemSet.end() )
+ if ( elemSet.find(el) != elemSet.end() )
nbInitElems++;
+ }
if ( nbInitElems < 2 ) {
- vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
- list<const SMDS_MeshElement*> newEdges;
- sweepElement( aMesh, node, newNodesItVec, newEdges );
+ bool NotCreateEdge = el->IsQuadratic() && el->IsMediumNode(node);
+ if(!NotCreateEdge) {
+ vector<TNodeOfNodeListMapItr> newNodesItVec( 1, nList );
+ list<const SMDS_MeshElement*> newEdges;
+ sweepElement( aMesh, node, newNodesItVec, newEdges, nbSteps );
+ }
}
}
TElemOfElemListMap::iterator itElem = newElemsMap.begin();
TElemOfVecOfNnlmiMap::iterator itElemNodes = elemNewNodesMap.begin();
- for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ )
- {
+ for ( ; itElem != newElemsMap.end(); itElem++, itElemNodes++ ) {
const SMDS_MeshElement* elem = itElem->first;
vector<TNodeOfNodeListMapItr>& vecNewNodes = itElemNodes->second;
- if ( elem->GetType() == SMDSAbs_Edge )
- {
- // create a ceiling edge
- aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
- vecNewNodes[ 1 ]->second.back() );
+ if ( elem->GetType() == SMDSAbs_Edge ) {
+ if(!elem->IsQuadratic()) {
+ // create a ceiling edge
+ aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back() );
+ }
+ else {
+ // create a ceiling edge
+ aMesh->AddEdge(vecNewNodes[ 0 ]->second.back(),
+ vecNewNodes[ 1 ]->second.back(),
+ vecNewNodes[ 2 ]->second.back());
+ }
}
if ( elem->GetType() != SMDSAbs_Face )
continue;
set<const SMDS_MeshElement*> avoidSet;
avoidSet.insert( elem );
- // loop on a face nodes
set<const SMDS_MeshNode*> aFaceLastNodes;
int iNode, nbNodes = vecNewNodes.size();
- for ( iNode = 0; iNode < nbNodes; iNode++ )
- {
- aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
- // look for free links of a face
- int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
- const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
- const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
- // check if a link is free
- if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet ))
- {
- hasFreeLinks = true;
- // make an edge and a ceiling for a new edge
- if ( !aMesh->FindEdge( n1, n2 ))
- aMesh->AddEdge( n1, n2 );
- n1 = vecNewNodes[ iNode ]->second.back();
- n2 = vecNewNodes[ iNext ]->second.back();
- if ( !aMesh->FindEdge( n1, n2 ))
- aMesh->AddEdge( n1, n2 );
+ if(!elem->IsQuadratic()) {
+ // loop on a face nodes
+ for ( iNode = 0; iNode < nbNodes; iNode++ ) {
+ aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
+ // look for free links of a face
+ int iNext = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
+ const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
+ const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+ // check if a link is free
+ if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) {
+ hasFreeLinks = true;
+ // make an edge and a ceiling for a new edge
+ if ( !aMesh->FindEdge( n1, n2 )) {
+ aMesh->AddEdge( n1, n2 );
+ }
+ n1 = vecNewNodes[ iNode ]->second.back();
+ n2 = vecNewNodes[ iNext ]->second.back();
+ if ( !aMesh->FindEdge( n1, n2 )) {
+ aMesh->AddEdge( n1, n2 );
+ }
+ }
+ }
+ }
+ else { // elem is quadratic face
+ int nbn = nbNodes/2;
+ for ( iNode = 0; iNode < nbn; iNode++ ) {
+ aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
+ int iNext = ( iNode + 1 == nbn ) ? 0 : iNode + 1;
+ const SMDS_MeshNode* n1 = vecNewNodes[ iNode ]->first;
+ const SMDS_MeshNode* n2 = vecNewNodes[ iNext ]->first;
+ // check if a link is free
+ if ( ! SMESH_MeshEditor::FindFaceInSet ( n1, n2, elemSet, avoidSet )) {
+ hasFreeLinks = true;
+ // make an edge and a ceiling for a new edge
+ // find medium node
+ const SMDS_MeshNode* n3 = vecNewNodes[ iNode+nbn ]->first;
+ if ( !aMesh->FindEdge( n1, n2, n3 )) {
+ aMesh->AddEdge( n1, n2, n3 );
+ }
+ n1 = vecNewNodes[ iNode ]->second.back();
+ n2 = vecNewNodes[ iNext ]->second.back();
+ n3 = vecNewNodes[ iNode+nbn ]->second.back();
+ if ( !aMesh->FindEdge( n1, n2, n3 )) {
+ aMesh->AddEdge( n1, n2, n3 );
+ }
+ }
+ }
+ for ( iNode = nbn; iNode < 2*nbn; iNode++ ) {
+ aFaceLastNodes.insert( vecNewNodes[ iNode ]->second.back() );
}
}
+
// sweep free links into faces
- if ( hasFreeLinks )
- {
+ if ( hasFreeLinks ) {
list<const SMDS_MeshElement*> & newVolumes = itElem->second;
- int iStep, nbSteps = vecNewNodes[0]->second.size();
+ int iStep; //, nbSteps = vecNewNodes[0]->second.size();
int iVol, volNb, nbVolumesByStep = newVolumes.size() / nbSteps;
set<const SMDS_MeshNode*> initNodeSet, faceNodeSet;
for ( iNode = 0; iNode < nbNodes; iNode++ )
initNodeSet.insert( vecNewNodes[ iNode ]->first );
- for ( volNb = 0; volNb < nbVolumesByStep; volNb++ )
- {
+ for ( volNb = 0; volNb < nbVolumesByStep; volNb++ ) {
list<const SMDS_MeshElement*>::iterator v = newVolumes.begin();
iVol = 0;
while ( iVol++ < volNb ) v++;
list< int > fInd;
SMDS_VolumeTool vTool( *v );
int iF, nbF = vTool.NbFaces();
- for ( iF = 0; iF < nbF; iF ++ )
+ for ( iF = 0; iF < nbF; iF ++ ) {
if (vTool.IsFreeFace( iF ) &&
vTool.GetFaceNodes( iF, faceNodeSet ) &&
initNodeSet != faceNodeSet) // except an initial face
fInd.push_back( iF );
+ }
if ( fInd.empty() )
continue;
// create faces for all steps
- for ( iStep = 0; iStep < nbSteps; iStep++ )
- {
+ for ( iStep = 0; iStep < nbSteps; iStep++ ) {
vTool.Set( *v );
vTool.SetExternalNormal();
list< int >::iterator ind = fInd.begin();
- for ( ; ind != fInd.end(); ind++ )
- {
+ for ( ; ind != fInd.end(); ind++ ) {
const SMDS_MeshNode** nodes = vTool.GetFaceNodes( *ind );
- switch ( vTool.NbFaceNodes( *ind ) ) {
+ int nbn = vTool.NbFaceNodes( *ind );
+ //switch ( vTool.NbFaceNodes( *ind ) ) {
+ switch ( nbn ) {
case 3:
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
case 4:
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
default:
{
- int nbPolygonNodes = vTool.NbFaceNodes( *ind );
- vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
- for (int inode = 0; inode < nbPolygonNodes; inode++) {
- polygon_nodes[inode] = nodes[inode];
+ if( (*v)->IsQuadratic() ) {
+ if(nbn==6) {
+ aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+ nodes[1], nodes[3], nodes[5]); break;
+ }
+ else {
+ aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+ nodes[1], nodes[3], nodes[5], nodes[7]);
+ break;
+ }
+ }
+ else {
+ int nbPolygonNodes = vTool.NbFaceNodes( *ind );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ aMesh->AddPolygonalFace(polygon_nodes);
}
- aMesh->AddPolygonalFace(polygon_nodes);
break;
}
}
// make a ceiling face with a normal external to a volume
SMDS_VolumeTool lastVol( itElem->second.back() );
+
int iF = lastVol.GetFaceIndex( aFaceLastNodes );
- if ( iF >= 0 )
- {
+ if ( iF >= 0 ) {
lastVol.SetExternalNormal();
const SMDS_MeshNode** nodes = lastVol.GetFaceNodes( iF );
- switch ( lastVol.NbFaceNodes( iF ) ) {
+ int nbn = lastVol.NbFaceNodes( iF );
+ switch ( nbn ) {
case 3:
if (!hasFreeLinks ||
!aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ]))
break;
default:
{
- int nbPolygonNodes = lastVol.NbFaceNodes( iF );
- vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
- for (int inode = 0; inode < nbPolygonNodes; inode++) {
- polygon_nodes[inode] = nodes[inode];
+ if(itElem->second.back()->IsQuadratic()) {
+ if(nbn==6) {
+ if (!hasFreeLinks ||
+ !aMesh->FindFace(nodes[0], nodes[2], nodes[4],
+ nodes[1], nodes[3], nodes[5]) ) {
+ aMesh->AddFace(nodes[0], nodes[2], nodes[4],
+ nodes[1], nodes[3], nodes[5]); break;
+ }
+ }
+ else { // nbn==8
+ if (!hasFreeLinks ||
+ !aMesh->FindFace(nodes[0], nodes[2], nodes[4], nodes[6],
+ nodes[1], nodes[3], nodes[5], nodes[7]) )
+ aMesh->AddFace(nodes[0], nodes[2], nodes[4], nodes[6],
+ nodes[1], nodes[3], nodes[5], nodes[7]);
+ }
+ }
+ else {
+ int nbPolygonNodes = lastVol.NbFaceNodes( iF );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+ aMesh->AddPolygonalFace(polygon_nodes);
}
- if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
- aMesh->AddPolygonalFace(polygon_nodes);
}
break;
}
}
-
} // loop on swept elements
}
MESSAGE( "RotationSweep()");
gp_Trsf aTrsf;
aTrsf.SetRotation( theAxis, theAngle );
+ gp_Trsf aTrsf2;
+ aTrsf2.SetRotation( theAxis, theAngle/2. );
gp_Lin aLine( theAxis );
double aSqTol = theTol * theTol;
// loop on theElems
set< const SMDS_MeshElement* >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
if ( !elem )
continue;
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
TNodeOfNodeListMapItr nIt = mapNewNodes.find( node );
- if ( nIt == mapNewNodes.end() )
- {
+ if ( nIt == mapNewNodes.end() ) {
nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
const SMDS_MeshNode * newNode = node;
for ( int i = 0; i < theNbSteps; i++ ) {
if ( !isOnAxis ) {
- aTrsf.Transforms( coord[0], coord[1], coord[2] );
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ // create two nodes
+ aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+ //aTrsf.Transforms( coord[0], coord[1], coord[2] );
+ newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ listNewNodes.push_back( newNode );
+ aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+ //aTrsf.Transforms( coord[0], coord[1], coord[2] );
+ }
+ else {
+ aTrsf.Transforms( coord[0], coord[1], coord[2] );
+ }
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
}
- listNewNodes.push_back( newNode );
+ listNewNodes.push_back( newNode );
+ }
+ }
+ else {
+ // if current elem is quadratic and current node is not medium
+ // we have to check - may be it is needed to insert additional nodes
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+ if(listNewNodes.size()==theNbSteps) {
+ listNewNodes.clear();
+ // make new nodes
+ gp_XYZ aXYZ( node->X(), node->Y(), node->Z() );
+ double coord[3];
+ aXYZ.Coord( coord[0], coord[1], coord[2] );
+ const SMDS_MeshNode * newNode = node;
+ for(int i = 0; i<theNbSteps; i++) {
+ aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+ newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ listNewNodes.push_back( newNode );
+ aTrsf2.Transforms( coord[0], coord[1], coord[2] );
+ newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ listNewNodes.push_back( newNode );
+ }
+ }
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+ sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], theNbSteps );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, theNbSteps );
}
{
SMESHDS_Mesh* aMesh = GetMeshDS();
+ int nbsteps = theParams.mySteps->Length();
+
TNodeOfNodeListMap mapNewNodes;
+ //TNodeOfNodeVecMap mapNewNodes;
TElemOfVecOfNnlmiMap mapElemNewNodes;
+ //TElemOfVecOfMapNodesMap mapElemNewNodes;
// loop on theElems
set< const SMDS_MeshElement* >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
// check element type
const SMDS_MeshElement* elem = (*itElem);
if ( !elem )
continue;
vector<TNodeOfNodeListMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
+ //vector<TNodeOfNodeVecMapItr> & newNodesItVec = mapElemNewNodes[ elem ];
newNodesItVec.reserve( elem->NbNodes() );
// loop on elem nodes
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
TNodeOfNodeListMap::iterator nIt = mapNewNodes.find( node );
- if ( nIt == mapNewNodes.end() )
- {
+ //TNodeOfNodeVecMap::iterator nIt = mapNewNodes.find( node );
+ if ( nIt == mapNewNodes.end() ) {
nIt = mapNewNodes.insert( make_pair( node, list<const SMDS_MeshNode*>() )).first;
+ //nIt = mapNewNodes.insert( make_pair( node, vector<const SMDS_MeshNode*>() )).first;
list<const SMDS_MeshNode*>& listNewNodes = nIt->second;
+ //vector<const SMDS_MeshNode*>& vecNewNodes = nIt->second;
+ //vecNewNodes.reserve(nbsteps);
// make new nodes
double coord[] = { node->X(), node->Y(), node->Z() };
- int nbsteps = theParams.mySteps->Length();
+ //int nbsteps = theParams.mySteps->Length();
for ( int i = 0; i < nbsteps; i++ ) {
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ // create additional node
+ double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1)/2.;
+ double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1)/2.;
+ double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1)/2.;
+ if( theFlags & EXTRUSION_FLAG_SEW ) {
+ const SMDS_MeshNode * newNode = CreateNode(x, y, z,
+ theTolerance, theParams.myNodes);
+ listNewNodes.push_back( newNode );
+ }
+ else {
+ const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+ listNewNodes.push_back( newNode );
+ }
+ }
//aTrsf.Transforms( coord[0], coord[1], coord[2] );
coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
theTolerance, theParams.myNodes);
listNewNodes.push_back( newNode );
+ //vecNewNodes[i]=newNode;
}
else {
const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
listNewNodes.push_back( newNode );
+ //vecNewNodes[i]=newNode;
+ }
+ }
+ }
+ else {
+ // if current elem is quadratic and current node is not medium
+ // we have to check - may be it is needed to insert additional nodes
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+ if(listNewNodes.size()==nbsteps) {
+ listNewNodes.clear();
+ double coord[] = { node->X(), node->Y(), node->Z() };
+ for ( int i = 0; i < nbsteps; i++ ) {
+ double x = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
+ double y = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
+ double z = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
+ if( theFlags & EXTRUSION_FLAG_SEW ) {
+ const SMDS_MeshNode * newNode = CreateNode(x, y, z,
+ theTolerance, theParams.myNodes);
+ listNewNodes.push_back( newNode );
+ }
+ else {
+ const SMDS_MeshNode * newNode = aMesh->AddNode(x, y, z);
+ listNewNodes.push_back( newNode );
+ }
+ coord[0] = coord[0] + theParams.myDir.X()*theParams.mySteps->Value(i+1);
+ coord[1] = coord[1] + theParams.myDir.Y()*theParams.mySteps->Value(i+1);
+ coord[2] = coord[2] + theParams.myDir.Z()*theParams.mySteps->Value(i+1);
+ if( theFlags & EXTRUSION_FLAG_SEW ) {
+ const SMDS_MeshNode * newNode = CreateNode(coord[0], coord[1], coord[2],
+ theTolerance, theParams.myNodes);
+ listNewNodes.push_back( newNode );
+ }
+ else {
+ const SMDS_MeshNode * newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
+ listNewNodes.push_back( newNode );
+ }
+ }
}
}
}
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+ sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem], nbsteps );
}
if( theFlags & EXTRUSION_FLAG_BOUNDARY ) {
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems );
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElems, nbsteps );
}
}
}
// make new node
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ // create additional node
+ double x = ( aPN1.X() + aPN0.X() )/2.;
+ double y = ( aPN1.Y() + aPN0.Y() )/2.;
+ double z = ( aPN1.Z() + aPN0.Z() )/2.;
+ const SMDS_MeshNode* newNode = aMesh->AddNode(x,y,z);
+ listNewNodes.push_back( newNode );
+ }
aX = aPN1.X();
aY = aPN1.Y();
aZ = aPN1.Z();
aDT0x = aDT1x;
}
}
+
+ else {
+ // if current elem is quadratic and current node is not medium
+ // we have to check - may be it is needed to insert additional nodes
+ if( elem->IsQuadratic() && !elem->IsMediumNode(node) ) {
+ list< const SMDS_MeshNode* > & listNewNodes = nIt->second;
+ if(listNewNodes.size()==aNbTP-1) {
+ vector<const SMDS_MeshNode*> aNodes(2*(aNbTP-1));
+ gp_XYZ P(node->X(), node->Y(), node->Z());
+ list< const SMDS_MeshNode* >::iterator it = listNewNodes.begin();
+ int i;
+ for(i=0; i<aNbTP-1; i++) {
+ const SMDS_MeshNode* N = *it;
+ double x = ( N->X() + P.X() )/2.;
+ double y = ( N->Y() + P.Y() )/2.;
+ double z = ( N->Z() + P.Z() )/2.;
+ const SMDS_MeshNode* newN = aMesh->AddNode(x,y,z);
+ aNodes[2*i] = newN;
+ aNodes[2*i+1] = N;
+ P = gp_XYZ(N->X(),N->Y(),N->Z());
+ }
+ listNewNodes.clear();
+ for(i=0; i<2*(aNbTP-1); i++) {
+ listNewNodes.push_back(aNodes[i]);
+ }
+ }
+ }
+ }
+
newNodesItVec.push_back( nIt );
}
// make new elements
- sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem] );
+ sweepElement( aMesh, elem, newNodesItVec, newElemsMap[elem],
+ newNodesItVec[0]->second.size() );
}
- makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements );
+ makeWalls( aMesh, mapNewNodes, newElemsMap, mapElemNewNodes, theElements,
+ aNbTP-1 );
return EXTR_OK;
}
// loop on theElems
set< const SMDS_MeshElement* >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
if ( !elem )
continue;
{ 0, 1, 2, 3, 4, 5, 6, 7 } // FORWARD
};
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
- {
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
const SMDS_MeshElement* elem = (*itElem);
if ( !elem || elem->GetType() == SMDSAbs_Node )
continue;
else
i = index[ nbNodes - 4 ];
+ if(elem->IsQuadratic()) {
+ static int anIds[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+ i = anIds;
+ if(needReverse) {
+ if(nbNodes==3) { // quadratic edge
+ static int anIds[] = {1,0,2};
+ i = anIds;
+ }
+ else if(nbNodes==6) { // quadratic triangle
+ static int anIds[] = {0,2,1,5,4,3};
+ i = anIds;
+ }
+ else if(nbNodes==8) { // quadratic quadrangle
+ static int anIds[] = {0,3,2,1,7,6,5,4};
+ i = anIds;
+ }
+ else if(nbNodes==10) { // quadratic tetrahedron of 10 nodes
+ static int anIds[] = {0,2,1,3,6,5,4,7,9,8};
+ i = anIds;
+ }
+ else if(nbNodes==13) { // quadratic pyramid of 13 nodes
+ static int anIds[] = {0,3,2,1,4,8,7,6,5,9,12,11,10};
+ i = anIds;
+ }
+ else if(nbNodes==15) { // quadratic pentahedron with 15 nodes
+ static int anIds[] = {0,2,1,3,5,4,8,7,6,11,10,9,12,14,13};
+ i = anIds;
+ }
+ else { // nbNodes==20 - quadratic hexahedron with 20 nodes
+ static int anIds[] = {0,3,2,1,4,7,6,5,11,10,9,8,15,14,13,12,16,19,18,17};
+ i = anIds;
+ }
+ }
+ }
+
// find transformed nodes
const SMDS_MeshNode* nodes[8];
int iNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
- {
+ while ( itN->more() ) {
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
TNodeNodeMap::iterator nodeMapIt = nodeMap.find( node );
if ( iNode != nbNodes )
continue; // not all nodes transformed
- if ( theCopy )
- {
+ if ( theCopy ) {
// add a new element
switch ( elemType ) {
case SMDSAbs_Edge:
- aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+ if ( nbNodes == 2 )
+ aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ] );
+ else
+ aMesh->AddEdge( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
break;
case SMDSAbs_Face:
if ( nbNodes == 3 )
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] );
- else
+ else if(nbNodes==4)
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ]);
+ else if(nbNodes==6)
+ aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5]);
+ else // nbNodes==8
+ aMesh->AddFace(nodes[0], nodes[1], nodes[2], nodes[3],
+ nodes[4], nodes[5], nodes[6], nodes[7]);
break;
case SMDSAbs_Volume:
if ( nbNodes == 4 )
else if ( nbNodes == 5 )
aMesh->AddVolume( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] , nodes[ 3 ],
nodes[ 4 ]);
+ else if(nbNodes==10)
+ aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9]);
+ else if(nbNodes==13)
+ aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12]);
+ else if(nbNodes==15)
+ aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12], nodes[13], nodes[14]);
+ else // nbNodes==20
+ aMesh->AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4],
+ nodes[5], nodes[6], nodes[7], nodes[8], nodes[9],
+ nodes[10], nodes[11], nodes[12], nodes[13], nodes[14],
+ nodes[15], nodes[16], nodes[17], nodes[18], nodes[19]);
break;
default:;
}
// Fill nodeNodeMap and elems
TListOfListOfNodes::iterator grIt = theGroupsOfNodes.begin();
- for ( ; grIt != theGroupsOfNodes.end(); grIt++ )
- {
+ for ( ; grIt != theGroupsOfNodes.end(); grIt++ ) {
list<const SMDS_MeshNode*>& nodes = *grIt;
list<const SMDS_MeshNode*>::iterator nIt = nodes.begin();
const SMDS_MeshNode* nToKeep = *nIt;
- for ( ; nIt != nodes.end(); nIt++ )
- {
+ for ( ; nIt != nodes.end(); nIt++ ) {
const SMDS_MeshNode* nToRemove = *nIt;
nodeNodeMap.insert( TNodeNodeMap::value_type( nToRemove, nToKeep ));
if ( nToRemove != nToKeep ) {
}
SMDS_ElemIteratorPtr invElemIt = nToRemove->GetInverseElementIterator();
- while ( invElemIt->more() )
- elems.insert( invElemIt->next() );
+ while ( invElemIt->more() ) {
+ const SMDS_MeshElement* elem = invElemIt->next();
+ elems.insert(elem);
+ }
}
}
// Change element nodes or remove an element
set<const SMDS_MeshElement*>::iterator eIt = elems.begin();
- for ( ; eIt != elems.end(); eIt++ )
- {
+ for ( ; eIt != elems.end(); eIt++ ) {
const SMDS_MeshElement* elem = *eIt;
int nbNodes = elem->NbNodes();
int aShapeId = FindShape( elem );
// get new seq of nodes
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() )
- {
+ while ( itN->more() ) {
const SMDS_MeshNode* n =
static_cast<const SMDS_MeshNode*>( itN->next() );
bool isOk = true;
int nbUniqueNodes = nodeSet.size();
- if ( nbNodes != nbUniqueNodes ) // some nodes stick
- {
+ if ( nbNodes != nbUniqueNodes ) { // some nodes stick
// Polygons and Polyhedral volumes
if (elem->IsPoly()) {
aMesh->SetMeshElementOnShape(newElem, aShapeId);
}
aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
- } else {
+ }
+ else {
rmElemIds.push_back(elem->GetID());
}
- } else if (elem->GetType() == SMDSAbs_Volume) {
+ }
+ else if (elem->GetType() == SMDSAbs_Volume) {
// Polyhedral volume
if (nbUniqueNodes < 4) {
rmElemIds.push_back(elem->GetID());
- } else {
+ }
+ else {
// each face has to be analized in order to check volume validity
const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
else
rmElemIds.push_back(elem->GetID());
- } else {
+ }
+ else {
rmElemIds.push_back(elem->GetID());
}
}
- } else {
+ }
+ else {
}
continue;
else
isOk = false;
break;
- case 8: { //////////////////////////////////// HEXAHEDRON
+ case 8: {
+ if(elem->IsQuadratic()) { // Quadratic quadrangle
+ // 1 5 2
+ // +---+---+
+ // | |
+ // | |
+ // 4+ +6
+ // | |
+ // | |
+ // +---+---+
+ // 0 7 3
+ isOk = false;
+ if(nbRepl==3) {
+ nbUniqueNodes = 6;
+ if( iRepl[0]==0 && iRepl[1]==1 && iRepl[2]==4 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[2];
+ uniqueNodes[2] = curNodes[3];
+ uniqueNodes[3] = curNodes[5];
+ uniqueNodes[4] = curNodes[6];
+ uniqueNodes[5] = curNodes[7];
+ isOk = true;
+ }
+ if( iRepl[0]==0 && iRepl[1]==3 && iRepl[2]==7 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[1];
+ uniqueNodes[2] = curNodes[2];
+ uniqueNodes[3] = curNodes[4];
+ uniqueNodes[4] = curNodes[5];
+ uniqueNodes[5] = curNodes[6];
+ isOk = true;
+ }
+ if( iRepl[0]==0 && iRepl[1]==4 && iRepl[2]==7 ) {
+ uniqueNodes[0] = curNodes[1];
+ uniqueNodes[1] = curNodes[2];
+ uniqueNodes[2] = curNodes[3];
+ uniqueNodes[3] = curNodes[5];
+ uniqueNodes[4] = curNodes[6];
+ uniqueNodes[5] = curNodes[0];
+ isOk = true;
+ }
+ if( iRepl[0]==1 && iRepl[1]==2 && iRepl[2]==5 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[1];
+ uniqueNodes[2] = curNodes[3];
+ uniqueNodes[3] = curNodes[4];
+ uniqueNodes[4] = curNodes[6];
+ uniqueNodes[5] = curNodes[7];
+ isOk = true;
+ }
+ if( iRepl[0]==1 && iRepl[1]==4 && iRepl[2]==5 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[2];
+ uniqueNodes[2] = curNodes[3];
+ uniqueNodes[3] = curNodes[1];
+ uniqueNodes[4] = curNodes[6];
+ uniqueNodes[5] = curNodes[7];
+ isOk = true;
+ }
+ if( iRepl[0]==2 && iRepl[1]==3 && iRepl[2]==6 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[1];
+ uniqueNodes[2] = curNodes[2];
+ uniqueNodes[3] = curNodes[4];
+ uniqueNodes[4] = curNodes[5];
+ uniqueNodes[5] = curNodes[7];
+ isOk = true;
+ }
+ if( iRepl[0]==2 && iRepl[1]==5 && iRepl[2]==6 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[1];
+ uniqueNodes[2] = curNodes[3];
+ uniqueNodes[3] = curNodes[4];
+ uniqueNodes[4] = curNodes[2];
+ uniqueNodes[5] = curNodes[7];
+ isOk = true;
+ }
+ if( iRepl[0]==3 && iRepl[1]==6 && iRepl[2]==7 ) {
+ uniqueNodes[0] = curNodes[0];
+ uniqueNodes[1] = curNodes[1];
+ uniqueNodes[2] = curNodes[2];
+ uniqueNodes[3] = curNodes[4];
+ uniqueNodes[4] = curNodes[5];
+ uniqueNodes[5] = curNodes[3];
+ isOk = true;
+ }
+ }
+ break;
+ }
+ //////////////////////////////////// HEXAHEDRON
isOk = false;
SMDS_VolumeTool hexa (elem);
hexa.SetExternalNormal();
}
aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
}
- } else {
+ }
+ else {
// Change regular element or polygon
aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes );
}
- } else {
+ }
+ else {
// Remove invalid regular element or invalid polygon
rmElemIds.push_back( elem->GetID() );
}
i1 = iNode - 1;
}
// find a n2 linked to n1
- for ( iNode = 0; iNode < 2; iNode++ ) {
- if ( iNode ) // node before n1
- n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
- else // node after n1
- n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
- if ( n == n2 )
- return elem;
+ if(!elem->IsQuadratic()) {
+ for ( iNode = 0; iNode < 2; iNode++ ) {
+ if ( iNode ) // node before n1
+ n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
+ else // node after n1
+ n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
+ if ( n == n2 )
+ return elem;
+ }
}
+ else { // analysis for quadratic elements
+ bool IsFind = false;
+ // check using only corner nodes
+ for ( iNode = 0; iNode < 2; iNode++ ) {
+ if ( iNode ) // node before n1
+ n = faceNodes[ i1 == 0 ? nbN/2 - 1 : i1 - 1 ];
+ else // node after n1
+ n = faceNodes[ i1 + 1 == nbN/2 ? 0 : i1 + 1 ];
+ if ( n == n2 )
+ IsFind = true;
+ }
+ if(IsFind) {
+ return elem;
+ }
+ else {
+ // check using all nodes
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while ( anIter->more() ) {
+ faceNodes[iNode] = static_cast<const SMDS_MeshNode*>(anIter->next());
+ if ( faceNodes[ iNode++ ] == n1 )
+ i1 = iNode - 1;
+ }
+ for ( iNode = 0; iNode < 2; iNode++ ) {
+ if ( iNode ) // node before n1
+ n = faceNodes[ i1 == 0 ? nbN - 1 : i1 - 1 ];
+ else // node after n1
+ n = faceNodes[ i1 + 1 == nbN ? 0 : i1 + 1 ];
+ if ( n == n2 ) {
+ return elem;
+ }
+ }
+ }
+ } // end analysis for quadratic elements
}
return 0;
}
theNodes.push_back( theFirstNode );
theNodes.push_back( theSecondNode );
- const SMDS_MeshNode* nodes [5], *nIgnore = theFirstNode, * nStart = theSecondNode;
+ //vector<const SMDS_MeshNode*> nodes;
+ const SMDS_MeshNode *nIgnore = theFirstNode, *nStart = theSecondNode;
set < const SMDS_MeshElement* > foundElems;
bool needTheLast = ( theLastNode != 0 );
- while ( nStart != theLastNode )
- {
+ while ( nStart != theLastNode ) {
if ( nStart == theFirstNode )
return !needTheLast;
SMDS_ElemIteratorPtr invElemIt = nStart->facesIterator();
while ( invElemIt->more() ) {
const SMDS_MeshElement* e = invElemIt->next();
- if ( e == curElem || foundElems.insert( e ).second )
- {
+ if ( e == curElem || foundElems.insert( e ).second ) {
// get nodes
- SMDS_ElemIteratorPtr nIt = e->nodesIterator();
int iNode = 0, nbNodes = e->NbNodes();
- while ( nIt->more() )
- nodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ const SMDS_MeshNode* nodes[nbNodes+1];
+ if(e->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(e);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while( anIter->more() ) {
+ nodes[ iNode++ ] = anIter->next();
+ }
+ }
+ else {
+ SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+ while ( nIt->more() )
+ nodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ }
nodes[ iNode ] = nodes[ 0 ];
// check 2 links
for ( iNode = 0; iNode < nbNodes; iNode++ )
MESSAGE(" Free Border 1 not found " );
aResult = SEW_BORDER1_NOT_FOUND;
}
- if (theSideIsFreeBorder)
- {
+ if (theSideIsFreeBorder) {
// Free border 2
// --------------
if (!findFreeBorder(theSideFirstNode, theSideSecondNode, theSideThirdNode,
if ( aResult != SEW_OK )
return aResult;
- if (!theSideIsFreeBorder)
- {
+ if (!theSideIsFreeBorder) {
// Side 2
// --------------
gp_XYZ Ps2( theSideSecondNode->X(), theSideSecondNode->Y(), theSideSecondNode->Z() );
double tol2 = 1.e-8;
gp_Vec Vbs1( Pb1 - Ps1 ),Vbs2( Pb2 - Ps2 );
- if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 )
- {
+ if ( Vbs1.SquareMagnitude() > tol2 || Vbs2.SquareMagnitude() > tol2 ) {
// Need node movement.
// find X and Z axes to create trsf
nBordXYZ.insert( TNodeXYZMap::value_type( n, xyz ));
}
}
- else
- {
+ else {
// just insert nodes XYZ in the nBordXYZ map
for ( nBordIt = bordNodes.begin(); nBordIt != bordNodes.end(); nBordIt++ ) {
const SMDS_MeshNode* n = *nBordIt;
const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes;
if ( isVolume ) // --volume
hasVolumes = true;
- else if ( nbNodes > 2 ) { // --face
+ //else if ( nbNodes > 2 ) { // --face
+ else if ( elem->GetType()==SMDSAbs_Face ) { // --face
// retrieve all face nodes and find iPrevNode - an index of the prevSideNode
- SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
- while ( nIt->more() ) {
- nodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
- if ( nodes[ iNode++ ] == prevSideNode )
- iPrevNode = iNode - 1;
+ if(elem->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while( anIter->more() ) {
+ nodes[ iNode ] = anIter->next();
+ if ( nodes[ iNode++ ] == prevSideNode )
+ iPrevNode = iNode - 1;
+ }
+ }
+ else {
+ SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
+ while ( nIt->more() ) {
+ nodes[ iNode ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ if ( nodes[ iNode++ ] == prevSideNode )
+ iPrevNode = iNode - 1;
+ }
}
// there are 2 links to check
nbNodes = 2;
if ( isVolume ) {
if ( !volume.IsLinked( n, prevSideNode ))
continue;
- } else {
+ }
+ else {
if ( iNode ) // a node before prevSideNode
n = nodes[ iPrevNode == 0 ? elem->NbNodes() - 1 : iPrevNode - 1 ];
else // a node after prevSideNode
int iNode = 0, il1, il2, i3, i4;
il1 = il2 = i3 = i4 = -1;
const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
- SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- if ( n == theBetweenNode1 )
- il1 = iNode;
- else if ( n == theBetweenNode2 )
- il2 = iNode;
- else if ( i3 < 0 )
- i3 = iNode;
- else
- i4 = iNode;
- nodes[ iNode++ ] = n;
+
+ if(theFace->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while( anIter->more() ) {
+ const SMDS_MeshNode* n = anIter->next();
+ if ( n == theBetweenNode1 )
+ il1 = iNode;
+ else if ( n == theBetweenNode2 )
+ il2 = iNode;
+ else if ( i3 < 0 )
+ i3 = iNode;
+ else
+ i4 = iNode;
+ nodes[ iNode++ ] = n;
+ }
+ }
+ else {
+ SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ if ( n == theBetweenNode1 )
+ il1 = iNode;
+ else if ( n == theBetweenNode2 )
+ il2 = iNode;
+ else if ( i3 < 0 )
+ i3 = iNode;
+ else
+ i4 = iNode;
+ nodes[ iNode++ ] = n;
+ }
}
if ( il1 < 0 || il2 < 0 || i3 < 0 )
return ;
// add nodes of face up to first node of link
bool isFLN = false;
- nodeIt = theFace->nodesIterator();
- while ( nodeIt->more() && !isFLN ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- poly_nodes[iNode++] = n;
- if (n == nodes[il1]) {
- isFLN = true;
- }
- }
- // add nodes to insert
- list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
- for (; nIt != aNodesToInsert.end(); nIt++) {
- poly_nodes[iNode++] = *nIt;
+ if(theFace->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(theFace);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while( anIter->more() && !isFLN ) {
+ const SMDS_MeshNode* n = anIter->next();
+ poly_nodes[iNode++] = n;
+ if (n == nodes[il1]) {
+ isFLN = true;
+ }
+ }
+ // add nodes to insert
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for (; nIt != aNodesToInsert.end(); nIt++) {
+ poly_nodes[iNode++] = *nIt;
+ }
+ // add nodes of face starting from last node of link
+ while ( anIter->more() ) {
+ poly_nodes[iNode++] = anIter->next();
+ }
}
-
- // add nodes of face starting from last node of link
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- poly_nodes[iNode++] = n;
+ else {
+ SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
+ while ( nodeIt->more() && !isFLN ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ poly_nodes[iNode++] = n;
+ if (n == nodes[il1]) {
+ isFLN = true;
+ }
+ }
+ // add nodes to insert
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for (; nIt != aNodesToInsert.end(); nIt++) {
+ poly_nodes[iNode++] = *nIt;
+ }
+ // add nodes of face starting from last node of link
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ poly_nodes[iNode++] = n;
+ }
}
// edit or replace the face
if (theFace->IsPoly()) {
aMesh->ChangePolygonNodes(theFace, poly_nodes);
-
- } else {
+ }
+ else {
int aShapeId = FindShape( theFace );
SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
return;
}
- // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
- int nbLinkNodes = 2 + aNodesToInsert.size();
- const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
- linkNodes[ 0 ] = nodes[ il1 ];
- linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
- list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
- for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
- linkNodes[ iNode++ ] = *nIt;
- }
- // decide how to split a quadrangle: compare possible variants
- // and choose which of splits to be a quadrangle
- int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad;
- if ( nbFaceNodes == 3 )
- {
- iBestQuad = nbSplits;
- i4 = i3;
- }
- else if ( nbFaceNodes == 4 )
- {
- SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio);
- double aBestRate = DBL_MAX;
- for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) {
- i1 = 0; i2 = 1;
- double aBadRate = 0;
- // evaluate elements quality
- for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) {
- if ( iSplit == iQuad ) {
- SMDS_FaceOfNodes quad (linkNodes[ i1++ ],
- linkNodes[ i2++ ],
- nodes[ i3 ],
- nodes[ i4 ]);
- aBadRate += getBadRate( &quad, aCrit );
+ if( !theFace->IsQuadratic() ) {
+
+ // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
+ int nbLinkNodes = 2 + aNodesToInsert.size();
+ const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
+ linkNodes[ 0 ] = nodes[ il1 ];
+ linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
+ linkNodes[ iNode++ ] = *nIt;
+ }
+ // decide how to split a quadrangle: compare possible variants
+ // and choose which of splits to be a quadrangle
+ int i1, i2, iSplit, nbSplits = nbLinkNodes - 1, iBestQuad;
+ if ( nbFaceNodes == 3 ) {
+ iBestQuad = nbSplits;
+ i4 = i3;
+ }
+ else if ( nbFaceNodes == 4 ) {
+ SMESH::Controls::NumericalFunctorPtr aCrit( new SMESH::Controls::AspectRatio);
+ double aBestRate = DBL_MAX;
+ for ( int iQuad = 0; iQuad < nbSplits; iQuad++ ) {
+ i1 = 0; i2 = 1;
+ double aBadRate = 0;
+ // evaluate elements quality
+ for ( iSplit = 0; iSplit < nbSplits; iSplit++ ) {
+ if ( iSplit == iQuad ) {
+ SMDS_FaceOfNodes quad (linkNodes[ i1++ ],
+ linkNodes[ i2++ ],
+ nodes[ i3 ],
+ nodes[ i4 ]);
+ aBadRate += getBadRate( &quad, aCrit );
+ }
+ else {
+ SMDS_FaceOfNodes tria (linkNodes[ i1++ ],
+ linkNodes[ i2++ ],
+ nodes[ iSplit < iQuad ? i4 : i3 ]);
+ aBadRate += getBadRate( &tria, aCrit );
+ }
}
- else {
- SMDS_FaceOfNodes tria (linkNodes[ i1++ ],
- linkNodes[ i2++ ],
- nodes[ iSplit < iQuad ? i4 : i3 ]);
- aBadRate += getBadRate( &tria, aCrit );
+ // choice
+ if ( aBadRate < aBestRate ) {
+ iBestQuad = iQuad;
+ aBestRate = aBadRate;
}
}
- // choice
- if ( aBadRate < aBestRate ) {
- iBestQuad = iQuad;
- aBestRate = aBadRate;
+ }
+
+ // create new elements
+ SMESHDS_Mesh *aMesh = GetMeshDS();
+ int aShapeId = FindShape( theFace );
+
+ i1 = 0; i2 = 1;
+ for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
+ SMDS_MeshElement* newElem = 0;
+ if ( iSplit == iBestQuad )
+ newElem = aMesh->AddFace (linkNodes[ i1++ ],
+ linkNodes[ i2++ ],
+ nodes[ i3 ],
+ nodes[ i4 ]);
+ else
+ newElem = aMesh->AddFace (linkNodes[ i1++ ],
+ linkNodes[ i2++ ],
+ nodes[ iSplit < iBestQuad ? i4 : i3 ]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ }
+
+ // change nodes of theFace
+ const SMDS_MeshNode* newNodes[ 4 ];
+ newNodes[ 0 ] = linkNodes[ i1 ];
+ newNodes[ 1 ] = linkNodes[ i2 ];
+ newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
+ newNodes[ 3 ] = nodes[ i4 ];
+ aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
+ } // end if(!theFace->IsQuadratic())
+ else { // theFace is quadratic
+ // we have to split theFace on simple triangles and one simple quadrangle
+ int tmp = il1/2;
+ int nbshift = tmp*2;
+ // shift nodes in nodes[] by nbshift
+ int i,j;
+ for(i=0; i<nbshift; i++) {
+ const SMDS_MeshNode* n = nodes[0];
+ for(j=0; j<nbFaceNodes-1; j++) {
+ nodes[j] = nodes[j+1];
}
+ nodes[nbFaceNodes-1] = n;
}
- }
+ il1 = il1 - nbshift;
+ // now have to insert nodes between n0 and n1 or n1 and n2 (see below)
+ // n0 n1 n2 n0 n1 n2
+ // +-----+-----+ +-----+-----+
+ // \ / | |
+ // \ / | |
+ // n5+ +n3 n7+ +n3
+ // \ / | |
+ // \ / | |
+ // + +-----+-----+
+ // n4 n6 n5 n4
+
+ // create new elements
+ SMESHDS_Mesh *aMesh = GetMeshDS();
+ int aShapeId = FindShape( theFace );
- // create new elements
- SMESHDS_Mesh *aMesh = GetMeshDS();
- int aShapeId = FindShape( theFace );
-
- i1 = 0; i2 = 1;
- for ( iSplit = 0; iSplit < nbSplits - 1; iSplit++ ) {
- SMDS_MeshElement* newElem = 0;
- if ( iSplit == iBestQuad )
- newElem = aMesh->AddFace (linkNodes[ i1++ ],
- linkNodes[ i2++ ],
- nodes[ i3 ],
- nodes[ i4 ]);
- else
- newElem = aMesh->AddFace (linkNodes[ i1++ ],
- linkNodes[ i2++ ],
- nodes[ iSplit < iBestQuad ? i4 : i3 ]);
- if ( aShapeId && newElem )
- aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ int n1,n2,n3;
+ if(nbFaceNodes==6) { // quadratic triangle
+ SMDS_MeshElement* newElem =
+ aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ if(theFace->IsMediumNode(nodes[il1])) {
+ // create quadrangle
+ newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[5]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ n1 = 1;
+ n2 = 2;
+ n3 = 3;
+ }
+ else {
+ // create quadrangle
+ newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[5]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ n1 = 0;
+ n2 = 1;
+ n3 = 5;
+ }
+ }
+ else { // nbFaceNodes==8 - quadratic quadrangle
+ SMDS_MeshElement* newElem =
+ aMesh->AddFace(nodes[3],nodes[4],nodes[5]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ newElem = aMesh->AddFace(nodes[5],nodes[6],nodes[7]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ newElem = aMesh->AddFace(nodes[5],nodes[7],nodes[3]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ if(theFace->IsMediumNode(nodes[il1])) {
+ // create quadrangle
+ newElem = aMesh->AddFace(nodes[0],nodes[1],nodes[3],nodes[7]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ n1 = 1;
+ n2 = 2;
+ n3 = 3;
+ }
+ else {
+ // create quadrangle
+ newElem = aMesh->AddFace(nodes[1],nodes[2],nodes[3],nodes[7]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ n1 = 0;
+ n2 = 1;
+ n3 = 7;
+ }
+ }
+ // create needed triangles using n1,n2,n3 and inserted nodes
+ int nbn = 2 + aNodesToInsert.size();
+ const SMDS_MeshNode* aNodes[nbn];
+ aNodes[0] = nodes[n1];
+ aNodes[nbn-1] = nodes[n2];
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
+ aNodes[iNode++] = *nIt;
+ }
+ for(i=1; i<nbn; i++) {
+ SMDS_MeshElement* newElem =
+ aMesh->AddFace(aNodes[i-1],aNodes[i],nodes[n3]);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+ }
+ // remove old quadratic face
+ aMesh->RemoveElement(theFace);
}
-
- // change nodes of theFace
- const SMDS_MeshNode* newNodes[ 4 ];
- newNodes[ 0 ] = linkNodes[ i1 ];
- newNodes[ 1 ] = linkNodes[ i2 ];
- newNodes[ 2 ] = nodes[ iSplit >= iBestQuad ? i3 : i4 ];
- newNodes[ 3 ] = nodes[ i4 ];
- aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 );
}
//=======================================================================
poly_nodes.push_back(*nIt);
}
}
- } else if (faceNodes[inode] == theBetweenNode2) {
+ }
+ else if (faceNodes[inode] == theBetweenNode2) {
if (faceNodes[inode + 1] == theBetweenNode1) {
nbInserted = theNodesToInsert.size();
}
poly_nodes.push_back(*nIt);
}
- } else {
+ }
+ else {
}
}
}
if (elem->IsPoly()) {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
- } else {
+ }
+ else {
int aShapeId = FindShape( elem );
SMDS_MeshElement* newElem =
if ( elem->GetType() == SMDSAbs_Face ) {
faceSet->insert( elem );
set <const SMDS_MeshNode*> faceNodeSet;
- SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
- while ( nodeIt->more() ) {
- const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
- nodeSet->insert( n );
- faceNodeSet.insert( n );
+ if(elem->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(elem);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while( anIter->more() ) {
+ const SMDS_MeshNode* n = anIter->next();
+ nodeSet->insert( n );
+ faceNodeSet.insert( n );
+ }
+ }
+ else {
+ SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ nodeSet->insert( n );
+ faceNodeSet.insert( n );
+ }
}
setOfFaceNodeSet.insert( faceNodeSet );
}
// face does not exist
// -------------------------------------------------------------------------
- if ( !volSet->empty() )
- {
+ if ( !volSet->empty() ) {
//int nodeSetSize = nodeSet->size();
// loop on given volumes
// no such a face is given but it still can exist, check it
if ( nbNodes == 3 ) {
aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] );
- } else if ( nbNodes == 4 ) {
+ }
+ else if ( nbNodes == 4 ) {
aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
- } else {
+ }
+ else {
vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
for (int inode = 0; inode < nbNodes; inode++) {
poly_nodes[inode] = fNodes[inode];
// create a temporary face
if ( nbNodes == 3 ) {
aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
- } else if ( nbNodes == 4 ) {
+ }
+ else if ( nbNodes == 4 ) {
aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
- } else {
+ }
+ else {
vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
for (int inode = 0; inode < nbNodes; inode++) {
poly_nodes[inode] = fNodes[inode];
// loop on links in linkList; find faces by links and append links
// of the found faces to linkList
list< TPairOfNodes >::iterator linkIt[] = { linkList[0].begin(), linkList[1].begin() } ;
- for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ )
- {
+ for ( ; linkIt[0] != linkList[0].end(); linkIt[0]++, linkIt[1]++ ) {
TPairOfNodes link[] = { *linkIt[0], *linkIt[1] };
long linkID = aLinkID_Gen.GetLinkID( link[0].first, link[0].second );
if ( linkIdSet.find( linkID ) == linkIdSet.end() )
// ---------------------------------------------------------------
const SMDS_MeshElement* face[] = { 0, 0 };
- const SMDS_MeshNode* faceNodes[ 2 ][ 5 ];
- const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ;
+ //const SMDS_MeshNode* faceNodes[ 2 ][ 5 ];
+ vector<const SMDS_MeshNode*> fnodes1(9);
+ vector<const SMDS_MeshNode*> fnodes2(9);
+ //const SMDS_MeshNode* notLinkNodes[ 2 ][ 2 ] = {{ 0, 0 },{ 0, 0 }} ;
+ vector<const SMDS_MeshNode*> notLinkNodes1(6);
+ vector<const SMDS_MeshNode*> notLinkNodes2(6);
int iLinkNode[2][2];
for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
const SMDS_MeshNode* n1 = link[iSide].first;
faceSet->erase( f );
// get face nodes and find ones of a link
iNode = 0;
- SMDS_ElemIteratorPtr nIt = f->nodesIterator();
- while ( nIt->more() ) {
- const SMDS_MeshNode* n =
- static_cast<const SMDS_MeshNode*>( nIt->next() );
- if ( n == n1 )
- iLinkNode[ iSide ][ 0 ] = iNode;
- else if ( n == n2 )
- iLinkNode[ iSide ][ 1 ] = iNode;
- else if ( notLinkNodes[ iSide ][ 0 ] )
- notLinkNodes[ iSide ][ 1 ] = n;
- else
- notLinkNodes[ iSide ][ 0 ] = n;
- faceNodes[ iSide ][ iNode++ ] = n;
+ int nbl = -1;
+ if(f->IsPoly()) {
+ if(iSide==0) {
+ fnodes1.resize(f->NbNodes()+1);
+ notLinkNodes1.resize(f->NbNodes()-2);
+ }
+ else {
+ fnodes2.resize(f->NbNodes()+1);
+ notLinkNodes2.resize(f->NbNodes()-2);
+ }
+ }
+ if(!f->IsQuadratic()) {
+ SMDS_ElemIteratorPtr nIt = f->nodesIterator();
+ while ( nIt->more() ) {
+ const SMDS_MeshNode* n =
+ static_cast<const SMDS_MeshNode*>( nIt->next() );
+ if ( n == n1 ) {
+ iLinkNode[ iSide ][ 0 ] = iNode;
+ }
+ else if ( n == n2 ) {
+ iLinkNode[ iSide ][ 1 ] = iNode;
+ }
+ //else if ( notLinkNodes[ iSide ][ 0 ] )
+ // notLinkNodes[ iSide ][ 1 ] = n;
+ //else
+ // notLinkNodes[ iSide ][ 0 ] = n;
+ else {
+ nbl++;
+ if(iSide==0)
+ notLinkNodes1[nbl] = n;
+ //notLinkNodes1.push_back(n);
+ else
+ notLinkNodes2[nbl] = n;
+ //notLinkNodes2.push_back(n);
+ }
+ //faceNodes[ iSide ][ iNode++ ] = n;
+ if(iSide==0) {
+ fnodes1[iNode++] = n;
+ }
+ else {
+ fnodes2[iNode++] = n;
+ }
+ }
+ }
+ else { // f->IsQuadratic()
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(f);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ while ( anIter->more() ) {
+ const SMDS_MeshNode* n =
+ static_cast<const SMDS_MeshNode*>( anIter->next() );
+ if ( n == n1 ) {
+ iLinkNode[ iSide ][ 0 ] = iNode;
+ }
+ else if ( n == n2 ) {
+ iLinkNode[ iSide ][ 1 ] = iNode;
+ }
+ else {
+ nbl++;
+ if(iSide==0) {
+ notLinkNodes1[nbl] = n;
+ }
+ else {
+ notLinkNodes2[nbl] = n;
+ }
+ }
+ if(iSide==0) {
+ fnodes1[iNode++] = n;
+ }
+ else {
+ fnodes2[iNode++] = n;
+ }
+ }
+ }
+ //faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ];
+ if(iSide==0) {
+ fnodes1[iNode] = fnodes1[0];
+ }
+ else {
+ fnodes2[iNode] = fnodes1[0];
}
- faceNodes[ iSide ][ iNode ] = faceNodes[ iSide ][ 0 ];
}
}
}
}
+
// check similarity of elements of the sides
if (aResult == SEW_OK && ( face[0] && !face[1] ) || ( !face[0] && face[1] )) {
MESSAGE("Correspondent face not found on side " << ( face[0] ? 1 : 0 ));
- if ( nReplaceMap.size() == 2 ) // faces on input nodes not found
+ if ( nReplaceMap.size() == 2 ) { // faces on input nodes not found
aResult = ( face[0] ? SEW_BAD_SIDE2_NODES : SEW_BAD_SIDE1_NODES );
- else
+ }
+ else {
aResult = SEW_TOPO_DIFF_SETS_OF_ELEMENTS;
+ }
break; // do not return because it s necessary to remove tmp faces
}
// set nodes to merge
// -------------------
- if ( face[0] && face[1] )
- {
+ if ( face[0] && face[1] ) {
int nbNodes = face[0]->NbNodes();
if ( nbNodes != face[1]->NbNodes() ) {
MESSAGE("Diff nb of face nodes");
break; // do not return because it s necessary to remove tmp faces
}
bool reverse[] = { false, false }; // order of notLinkNodes of quadrangle
- if ( nbNodes == 3 )
+ if ( nbNodes == 3 ) {
+ //nReplaceMap.insert( TNodeNodeMap::value_type
+ // ( notLinkNodes[0][0], notLinkNodes[1][0] ));
nReplaceMap.insert( TNodeNodeMap::value_type
- ( notLinkNodes[0][0], notLinkNodes[1][0] ));
+ ( notLinkNodes1[0], notLinkNodes2[0] ));
+ }
else {
for ( iSide = 0; iSide < 2; iSide++ ) { // loop on 2 sides
// analyse link orientation in faces
reverse[ iSide ] = !reverse[ iSide ];
}
if ( reverse[0] == reverse[1] ) {
- nReplaceMap.insert( TNodeNodeMap::value_type
- ( notLinkNodes[0][0], notLinkNodes[1][0] ));
- nReplaceMap.insert( TNodeNodeMap::value_type
- ( notLinkNodes[0][1], notLinkNodes[1][1] ));
+ //nReplaceMap.insert( TNodeNodeMap::value_type
+ // ( notLinkNodes[0][0], notLinkNodes[1][0] ));
+ //nReplaceMap.insert( TNodeNodeMap::value_type
+ // ( notLinkNodes[0][1], notLinkNodes[1][1] ));
+ for(int nn=0; nn<nbNodes-2; nn++) {
+ nReplaceMap.insert( TNodeNodeMap::value_type
+ ( notLinkNodes1[nn], notLinkNodes2[nn] ));
+ }
}
else {
- nReplaceMap.insert( TNodeNodeMap::value_type
- ( notLinkNodes[0][0], notLinkNodes[1][1] ));
- nReplaceMap.insert( TNodeNodeMap::value_type
- ( notLinkNodes[0][1], notLinkNodes[1][0] ));
+ //nReplaceMap.insert( TNodeNodeMap::value_type
+ // ( notLinkNodes[0][0], notLinkNodes[1][1] ));
+ //nReplaceMap.insert( TNodeNodeMap::value_type
+ // ( notLinkNodes[0][1], notLinkNodes[1][0] ));
+ for(int nn=0; nn<nbNodes-2; nn++) {
+ nReplaceMap.insert( TNodeNodeMap::value_type
+ ( notLinkNodes1[nn], notLinkNodes2[nbNodes-3-nn] ));
+ }
}
}
// add other links of the faces to linkList
// -----------------------------------------
- const SMDS_MeshNode** nodes = faceNodes[ 0 ];
- for ( iNode = 0; iNode < nbNodes; iNode++ )
- {
- linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] );
+ //const SMDS_MeshNode** nodes = faceNodes[ 0 ];
+ for ( iNode = 0; iNode < nbNodes; iNode++ ) {
+ //linkID = aLinkID_Gen.GetLinkID( nodes[iNode], nodes[iNode+1] );
+ linkID = aLinkID_Gen.GetLinkID( fnodes1[iNode], fnodes1[iNode+1] );
pair< set<long>::iterator, bool > iter_isnew = linkIdSet.insert( linkID );
if ( !iter_isnew.second ) { // already in a set: no need to process
linkIdSet.erase( iter_isnew.first );
}
else // new in set == encountered for the first time: add
{
- const SMDS_MeshNode* n1 = nodes[ iNode ];
- const SMDS_MeshNode* n2 = nodes[ iNode + 1];
+ //const SMDS_MeshNode* n1 = nodes[ iNode ];
+ //const SMDS_MeshNode* n2 = nodes[ iNode + 1];
+ const SMDS_MeshNode* n1 = fnodes1[ iNode ];
+ const SMDS_MeshNode* n2 = fnodes1[ iNode + 1];
linkList[0].push_back ( TPairOfNodes( n1, n2 ));
linkList[1].push_back ( TPairOfNodes( nReplaceMap[n1], nReplaceMap[n2] ));
}
// loop on nodes replacement map
TNodeNodeMap::iterator nReplaceMapIt = nReplaceMap.begin(), nnIt;
for ( ; nReplaceMapIt != nReplaceMap.end(); nReplaceMapIt++ )
- if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second )
- {
+ if ( (*nReplaceMapIt).first != (*nReplaceMapIt).second ) {
const SMDS_MeshNode* nToRemove = (*nReplaceMapIt).first;
nodeIDsToRemove.push_back( nToRemove->GetID() );
// loop on elements sharing nToRemove
if ( nbReplaced )
aMesh->ChangeElementNodes( e, nodes, nbNodes );
}
- }
+ }
Remove( nodeIDsToRemove, true );
anActor = myActor;
if (anActor != 0)
{
+ // skl 07.02.2006
+ SMDS_Mesh* aMesh = myActor->GetObject()->GetMesh();
+ if( myFilterType == SMESHGUI_TriaFilter ||
+ myFilterType == SMESHGUI_QuadFilter ||
+ myFilterType == SMESHGUI_FaceFilter ) {
+ SMDS_FaceIteratorPtr it = aMesh->facesIterator();
+ while(it->more()) {
+ const SMDS_MeshFace* f = it->next();
+ if(myFilterType == SMESHGUI_FaceFilter) {
+ myIds.Add(f->GetID());
+ }
+ else if( myFilterType==SMESHGUI_TriaFilter &&
+ ( f->NbNodes()==3 || f->NbNodes()==6 ) ) {
+ myIds.Add(f->GetID());
+ }
+ else if( myFilterType==SMESHGUI_QuadFilter &&
+ ( f->NbNodes()==4 || f->NbNodes()==8 ) ) {
+ myIds.Add(f->GetID());
+ }
+ }
+ }
+ else if(myFilterType == SMESHGUI_VolumeFilter) {
+ SMDS_VolumeIteratorPtr it = aMesh->volumesIterator();
+ while(it->more()) {
+ const SMDS_MeshVolume* f = it->next();
+ myIds.Add(f->GetID());
+ }
+ }
+ /* commented by skl 07.02.2006
TVisualObjPtr aVisualObj = anActor->GetObject();
vtkUnstructuredGrid* aGrid = aVisualObj->GetUnstructuredGrid();
if (aGrid != 0) {
}
}
}
+ */
}
}
StdMeshers_AutomaticLength.hxx \
StdMeshers_Distribution.hxx \
StdMeshers_QuadranglePreference.hxx \
+ StdMeshers_Helper.hxx \
StdMeshers_QuadraticMesh.hxx
EXPORT_PYSCRIPTS =
StdMeshers_AutomaticLength.cxx \
StdMeshers_Distribution.cxx \
StdMeshers_QuadranglePreference.cxx \
+ StdMeshers_Helper.cxx \
StdMeshers_QuadraticMesh.cxx
LIB_SERVER_IDL =
--- /dev/null
+// File: StdMeshers_Helper.cxx
+// Created: 15.02.06 15:22:41
+// Author: Sergey KUUL
+// Copyright: Open CASCADE 2006
+
+
+#include "StdMeshers_Helper.hxx"
+
+#include "TopTools_MapOfShape.hxx"
+#include "BRepTools.hxx"
+#include "BRepTools_WireExplorer.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMESH_subMesh.hxx"
+#include "Geom2d_Curve.hxx"
+#include "Geom_Curve.hxx"
+#include "Geom_Surface.hxx"
+#include "BRep_Tool.hxx"
+#include "gp_Pnt2d.hxx"
+
+
+//=======================================================================
+//function : CheckShape
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Helper::IsQuadraticSubMesh(const TopoDS_Shape& aSh,
+ const bool QuadMode)
+{
+ SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS();
+ myShapeID = meshDS->ShapeToIndex(aSh);
+ myCreateQuadratic = false;
+ if(QuadMode) {
+ // we can create quadratic elements only if each elements
+ // created on given shape is quadratic
+ // also we have to fill myNLinkNodeMap
+ myCreateQuadratic = true;
+ if(aSh.ShapeType()!=TopAbs_FACE) {
+ for (TopExp_Explorer exp(aSh, TopAbs_FACE); exp.More() && myCreateQuadratic; exp.Next()) {
+ const TopoDS_Face& F = TopoDS::Face(exp.Current());
+ SMDS_ElemIteratorPtr itf = GetMesh()->GetSubMesh(F)->GetSubMeshDS()->GetElements();
+ while(itf->more()) {
+ const SMDS_MeshElement* f = itf->next();
+ if( f->GetType()==SMDSAbs_Face && !f->IsQuadratic() ) {
+ myCreateQuadratic = false;
+ break;
+ }
+ SMDS_ElemIteratorPtr itn = f->nodesIterator();
+ if(f->NbNodes()==6) {
+ const SMDS_MeshNode* Ns[6];
+ int i = 0;
+ while(itn->more()) {
+ Ns[i++] = static_cast<const SMDS_MeshNode*>( itn->next() );
+ }
+ AddNLinkNode(Ns[0],Ns[1],Ns[3]);
+ AddNLinkNode(Ns[1],Ns[2],Ns[4]);
+ AddNLinkNode(Ns[2],Ns[0],Ns[5]);
+ }
+ else if(f->NbNodes()==8) {
+ const SMDS_MeshNode* Ns[8];
+ int i = 0;
+ while(itn->more()) {
+ Ns[i++] = static_cast<const SMDS_MeshNode*>( itn->next() );
+ }
+ AddNLinkNode(Ns[0],Ns[1],Ns[4]);
+ AddNLinkNode(Ns[1],Ns[2],Ns[5]);
+ AddNLinkNode(Ns[2],Ns[3],Ns[6]);
+ AddNLinkNode(Ns[3],Ns[0],Ns[7]);
+ }
+ }
+ }
+ }
+ else {
+ TopTools_MapOfShape aMap;
+ // check edges
+ const TopoDS_Face& F = TopoDS::Face(aSh);
+ const TopoDS_Wire& W = BRepTools::OuterWire(F);
+ BRepTools_WireExplorer wexp (W, F);
+ for (wexp.Init(W, F); wexp.More() && myCreateQuadratic; wexp.Next()) {
+ const TopoDS_Edge& E = wexp.Current();
+ if(aMap.Contains(E))
+ continue;
+ aMap.Add(E);
+ SMDS_ElemIteratorPtr it = GetMesh()->GetSubMesh(E)->GetSubMeshDS()->GetElements();
+ while(it->more()) {
+ const SMDS_MeshElement* e = it->next();
+ if( e->GetType()==SMDSAbs_Edge && !e->IsQuadratic() ) {
+ myCreateQuadratic = false;
+ break;
+ }
+ // fill NLinkNodeMap
+ SMDS_ElemIteratorPtr nodeIt = e->nodesIterator();
+ const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+ myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
+ myNLinkNodeMap[link] = n3;
+ }
+ }
+ }
+ }
+
+ if(!myCreateQuadratic) {
+ myNLinkNodeMap.clear();
+ }
+
+ return myCreateQuadratic;
+}
+
+
+//=======================================================================
+//function : IsMedium
+//purpose :
+//=======================================================================
+
+bool StdMeshers_Helper::IsMedium(const SMDS_MeshNode* n)
+{
+ SMDS_ElemIteratorPtr it = n->GetInverseElementIterator();
+ while (it->more()) {
+ const SMDS_MeshElement* elem = it->next();
+ return elem->IsMediumNode(n);
+ }
+ return false;
+}
+
+
+//=======================================================================
+//function : AddNLinkNode
+//purpose :
+//=======================================================================
+/*!
+ * Auxilary function for filling myNLinkNodeMap
+ */
+void StdMeshers_Helper::AddNLinkNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n12)
+{
+ NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+ ItNLinkNode itLN = myNLinkNodeMap.find( link );
+ if ( itLN == myNLinkNodeMap.end() ) {
+ // add new record to map
+ myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
+ }
+}
+
+
+//=======================================================================
+//function : GetNodeUV
+//purpose :
+//=======================================================================
+/*!
+ * Auxilary function for GetMediumNode()
+ */
+gp_XY StdMeshers_Helper::GetNodeUV(const TopoDS_Face& F,
+ const SMDS_MeshNode* n)
+{
+ gp_Pnt2d p2d;
+ const SMDS_PositionPtr Pos = n->GetPosition();
+ if(Pos->GetTypeOfPosition()==SMDS_TOP_FACE) {
+//cout<<"face"<<endl;
+ // node has position on face
+ const SMDS_FacePosition* fpos =
+ static_cast<const SMDS_FacePosition*>(n->GetPosition().get());
+ p2d = gp_Pnt2d(fpos->GetUParameter(),fpos->GetVParameter());
+//cout<<"fpos->GetUParameter()="<<fpos->GetUParameter()<<" fpos->GetVParameter()="<<fpos->GetVParameter()<<endl;
+ }
+ else if(Pos->GetTypeOfPosition()==SMDS_TOP_EDGE) {
+ // node has position on edge => it is needed to find
+ // corresponding edge from face, get pcurve for this
+ // edge and recieve value from this pcurve
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(n->GetPosition().get());
+ double param = epos->GetUParameter();
+ SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS();
+ int edgeID = Pos->GetShapeId();
+ const TopoDS_Edge& E = TopoDS::Edge(meshDS->IndexToShape(edgeID));
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ p2d = C2d->Value(param);
+ }
+ else { // vertex position
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ const TopoDS_Wire& W = BRepTools::OuterWire(F);
+ BRepTools_WireExplorer wexp (W, F);
+ TopoDS_Edge E;
+ for (wexp.Init(W, F); wexp.More(); wexp.Next()) {
+ E = wexp.Current();
+ TopoDS_Vertex V1 = TopExp::FirstVertex(E);
+ TopoDS_Vertex V2 = TopExp::LastVertex(E);
+ if( meshDS->ShapeToIndex(V1) != Pos->GetShapeId() &&
+ meshDS->ShapeToIndex(V2) != Pos->GetShapeId() ) continue;
+ double f2, l2;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f2, l2);
+ double f, l;
+ TopLoc_Location L;
+ Handle(Geom_Curve) C = BRep_Tool::Curve(E, L, f, l);
+ gp_Pnt P = C->Value(f);
+ if(!L.IsIdentity()) P = P.Transformed(L.Transformation());
+ double tol = BRep_Tool::Tolerance(E);
+ double dx = n->X() - P.X();
+ double dy = n->Y() - P.Y();
+ double dz = n->Z() - P.Z();
+ double dist = sqrt(dx*dx + dy*dy + dz*dz);
+ if(dist<tol) {
+ p2d = C2d->Value(f2);
+ }
+ else {
+ p2d = C2d->Value(l2);
+ }
+ }
+ }
+ return p2d.XY();
+}
+
+
+//=======================================================================
+//function : GetMediumNode
+//purpose :
+//=======================================================================
+/*!
+ * Special function for search or creation medium node
+ */
+const SMDS_MeshNode* StdMeshers_Helper::GetMediumNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const bool force3d)
+{
+//cout<<"n1: "<<n1;
+//cout<<"n2: "<<n2;
+ NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+ ItNLinkNode itLN = myNLinkNodeMap.find( link );
+ if ( itLN != myNLinkNodeMap.end() ) {
+ return (*itLN).second;
+ }
+ else {
+ // create medium node
+ SMDS_MeshNode* n12;
+ SMESHDS_Mesh* meshDS = GetMesh()->GetMeshDS();
+ if(!force3d) {
+ // we try to create medium node using UV parameters of
+ // nodes, else - medium between corresponding 3d points
+ const SMDS_PositionPtr Pos1 = n1->GetPosition();
+ const SMDS_PositionPtr Pos2 = n2->GetPosition();
+ int faceID = -1;
+ if( Pos1->GetTypeOfPosition()==SMDS_TOP_FACE ) {
+ faceID = Pos1->GetShapeId();
+ }
+ else if( Pos2->GetTypeOfPosition()==SMDS_TOP_FACE ) {
+ faceID = Pos2->GetShapeId();
+ }
+ if(faceID>-1) {
+ TopoDS_Face F = TopoDS::Face(meshDS->IndexToShape(faceID));
+ gp_XY p1 = GetNodeUV(F,n1);
+ gp_XY p2 = GetNodeUV(F,n2);
+ double u = (p1.X()+p2.X())/2.;
+ double v = (p1.Y()+p2.Y())/2.;
+ Handle(Geom_Surface) S = BRep_Tool::Surface(F);
+ gp_Pnt P = S->Value(u, v);
+ n12 = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ meshDS->SetNodeOnFace(n12, faceID, u, v);
+ myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
+ return n12;
+ }
+ }
+ // 3d variant
+ double x = ( n1->X() + n2->X() )/2.;
+ double y = ( n1->Y() + n2->Y() )/2.;
+ double z = ( n1->Z() + n2->Z() )/2.;
+ n12 = meshDS->AddNode(x,y,z);
+ meshDS->SetNodeInVolume(n12, myShapeID);
+ myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n12));
+ return n12;
+ }
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose :
+//=======================================================================
+/*!
+ * Special function for creation quadratic triangle
+ */
+SMDS_MeshFace* StdMeshers_Helper::AddFace(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3)
+{
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ if(!myCreateQuadratic) {
+ return meshDS->AddFace(n1, n2, n3);
+ }
+
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,false);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,false);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,false);
+
+ return meshDS->AddFace(n1, n2, n3, n12, n23, n31);
+}
+
+
+//=======================================================================
+//function : AddFace
+//purpose :
+//=======================================================================
+/*!
+ * Special function for creation quadratic quadrangle
+ */
+SMDS_MeshFace* StdMeshers_Helper::AddFace(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4)
+{
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ if(!myCreateQuadratic) {
+ return meshDS->AddFace(n1, n2, n3, n4);
+ }
+
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,false);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,false);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,false);
+ const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,false);
+
+ return meshDS->AddFace(n1, n2, n3, n4, n12, n23, n34, n41);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose :
+//=======================================================================
+/*!
+ * Special function for creation quadratic volume
+ */
+SMDS_MeshVolume* StdMeshers_Helper::AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4,
+ const SMDS_MeshNode* n5,
+ const SMDS_MeshNode* n6)
+{
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ if(!myCreateQuadratic) {
+ return meshDS->AddVolume(n1, n2, n3, n4, n5, n6);
+ }
+
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,true);
+
+ const SMDS_MeshNode* n45 = GetMediumNode(n4,n5,true);
+ const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,true);
+ const SMDS_MeshNode* n64 = GetMediumNode(n6,n4,true);
+
+ const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,true);
+ const SMDS_MeshNode* n25 = GetMediumNode(n2,n5,true);
+ const SMDS_MeshNode* n36 = GetMediumNode(n3,n6,true);
+
+ return meshDS->AddVolume(n1, n2, n3, n4, n5, n6,
+ n12, n23, n31, n45, n56, n64, n14, n25, n36);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose :
+//=======================================================================
+/*!
+ * Special function for creation quadratic volume
+ */
+SMDS_MeshVolume* StdMeshers_Helper::AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4)
+{
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ if(!myCreateQuadratic) {
+ return meshDS->AddVolume(n1, n2, n3, n4);
+ }
+
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true);
+ const SMDS_MeshNode* n31 = GetMediumNode(n3,n1,true);
+
+ const SMDS_MeshNode* n14 = GetMediumNode(n1,n4,true);
+ const SMDS_MeshNode* n24 = GetMediumNode(n2,n4,true);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,true);
+
+ return meshDS->AddVolume(n1, n2, n3, n4, n12, n23, n31, n14, n24, n34);
+}
+
+
+//=======================================================================
+//function : AddVolume
+//purpose :
+//=======================================================================
+/*!
+ * Special function for creation quadratic volume
+ */
+SMDS_MeshVolume* StdMeshers_Helper::AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4,
+ const SMDS_MeshNode* n5,
+ const SMDS_MeshNode* n6,
+ const SMDS_MeshNode* n7,
+ const SMDS_MeshNode* n8)
+{
+ SMESHDS_Mesh * meshDS = GetMesh()->GetMeshDS();
+ if(!myCreateQuadratic) {
+ return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8);
+ }
+
+ const SMDS_MeshNode* n12 = GetMediumNode(n1,n2,true);
+ const SMDS_MeshNode* n23 = GetMediumNode(n2,n3,true);
+ const SMDS_MeshNode* n34 = GetMediumNode(n3,n4,true);
+ const SMDS_MeshNode* n41 = GetMediumNode(n4,n1,true);
+
+ const SMDS_MeshNode* n56 = GetMediumNode(n5,n6,true);
+ const SMDS_MeshNode* n67 = GetMediumNode(n6,n7,true);
+ const SMDS_MeshNode* n78 = GetMediumNode(n7,n8,true);
+ const SMDS_MeshNode* n85 = GetMediumNode(n8,n5,true);
+
+ const SMDS_MeshNode* n15 = GetMediumNode(n1,n5,true);
+ const SMDS_MeshNode* n26 = GetMediumNode(n2,n6,true);
+ const SMDS_MeshNode* n37 = GetMediumNode(n3,n7,true);
+ const SMDS_MeshNode* n48 = GetMediumNode(n4,n8,true);
+
+ return meshDS->AddVolume(n1, n2, n3, n4, n5, n6, n7, n8,
+ n12, n23, n34, n41, n56, n67,
+ n78, n85, n15, n26, n37, n48);
+}
+
+
--- /dev/null
+// File: StdMeshers_Helper.hxx
+// Created: 15.02.06 14:48:09
+// Author: Sergey KUUL
+// Copyright: Open CASCADE 2006
+
+
+#ifndef StdMeshers_Helper_HeaderFile
+#define StdMeshers_Helper_HeaderFile
+
+#include <SMESH_Mesh.hxx>
+#include <TopoDS_Shape.hxx>
+#include <SMDS_MeshNode.hxx>
+#include <TopoDS_Face.hxx>
+#include <gp_XY.hxx>
+
+#include <map>
+
+typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> NLink;
+typedef map<NLink, const SMDS_MeshNode*> NLinkNodeMap;
+typedef map<NLink, const SMDS_MeshNode*>::iterator ItNLinkNode;
+
+/// Class StdMeshers_Helper
+//
+
+class StdMeshers_Helper
+{
+ public:
+ // ---------- PUBLIC METHODS ----------
+
+ /// Empty constructor
+ StdMeshers_Helper(SMESH_Mesh& theMesh)
+ { myMesh=(void *)&theMesh; myCreateQuadratic = false; }
+
+ SMESH_Mesh* GetMesh() const
+ { return (SMESH_Mesh*)myMesh; }
+
+ /// Copy constructor
+ //Standard_EXPORT StdMeshers_Helper (const StdMeshers_Helper& theOther);
+
+ /// Destructor
+ //Standard_EXPORT virtual ~StdMeshers_Helper ();
+
+ /**
+ * Check submesh for given shape
+ * If QuadMode is true: check if all elements on this shape
+ * are quadratic, if yes => set true to myCreateQuadratic
+ * (default value is false). Also fill myNLinkNodeMap
+ * Returns myCreateQuadratic
+ */
+ bool IsQuadraticSubMesh(const TopoDS_Shape& aSh, const bool QuadMode);
+
+ /**
+ * Returns true if given node is medium
+ */
+ bool IsMedium(const SMDS_MeshNode* n);
+
+ /**
+ * Auxilary function for filling myNLinkNodeMap
+ */
+ void AddNLinkNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n12);
+
+ /**
+ * Auxilary function for filling myNLinkNodeMap
+ */
+ void AddNLinkNodeMap(const NLinkNodeMap& aMap)
+ { myNLinkNodeMap.insert(aMap.begin(), aMap.end()); }
+
+ /**
+ * Returns myNLinkNodeMap
+ */
+ const NLinkNodeMap& GetNLinkNodeMap() { return myNLinkNodeMap; }
+
+ /**
+ * Auxilary function for GetMediumNode()
+ */
+ gp_XY GetNodeUV(const TopoDS_Face& F,
+ const SMDS_MeshNode* n);
+
+ /**
+ * Special function for search or creation medium node
+ */
+ const SMDS_MeshNode* GetMediumNode(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const bool force3d);
+ /**
+ * Special function for creation quadratic triangle
+ */
+ SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3);
+
+ /**
+ * Special function for creation quadratic quadrangle
+ */
+ SMDS_MeshFace* AddFace(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4);
+
+ /**
+ * Special function for creation quadratic tetraahedron
+ */
+ SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4);
+
+ /**
+ * Special function for creation quadratic pentahedron
+ */
+ SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4,
+ const SMDS_MeshNode* n5,
+ const SMDS_MeshNode* n6);
+
+ /**
+ * Special function for creation quadratic hexahedron
+ */
+ SMDS_MeshVolume* AddVolume(const SMDS_MeshNode* n1,
+ const SMDS_MeshNode* n2,
+ const SMDS_MeshNode* n3,
+ const SMDS_MeshNode* n4,
+ const SMDS_MeshNode* n5,
+ const SMDS_MeshNode* n6,
+ const SMDS_MeshNode* n7,
+ const SMDS_MeshNode* n8);
+
+
+
+ private:
+
+ void* myMesh;
+
+ int myShapeID;
+
+ // Key for creation quadratic faces
+ bool myCreateQuadratic;
+
+ // special map for using during creation quadratic faces
+ NLinkNodeMap myNLinkNodeMap;
+
+};
+
+
+#endif
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TColStd_ListIteratorOfListOfInteger.hxx>
+#include <TColStd_MapOfInteger.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Surface.hxx>
return true;
}
+
//=============================================================================
/*!
* Hexahedron mesh on hexaedron like form
const TopoDS_Shape & aShape)throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
- MESSAGE("StdMeshers_Hexa_3D::Compute");
- //bool isOk = false;
- SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
- //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
-
- // 0. - shape and face mesh verification
- // 0.1 - shape must be a solid (or a shell) with 6 faces
- //MESSAGE("---");
-
- vector < SMESH_subMesh * >meshFaces;
- for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next())
- {
- SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
- ASSERT(aSubMesh);
- meshFaces.push_back(aSubMesh);
- }
- if (meshFaces.size() != 6)
- {
- SCRUTE(meshFaces.size());
-// ASSERT(0);
- return false;
- }
-
- // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
- //MESSAGE("---");
-
- for (int i = 0; i < 6; i++)
- {
- TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
- SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
- string algoName = algo->GetName();
- bool isAllQuad = false;
- if (algoName == "Quadrangle_2D") {
- SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
- if ( sm ) {
- isAllQuad = true;
- SMDS_ElemIteratorPtr eIt = sm->GetElements();
- while ( isAllQuad && eIt->more() )
- isAllQuad = ( eIt->next()->NbNodes() == 4 );
- }
- }
- if ( ! isAllQuad ) {
- //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
- bool bIsOk;
- //
- bIsOk=ComputePentahedralMesh(aMesh, aShape);
- if (bIsOk) {
- return true;
- }
- //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t
- SCRUTE(algoName);
- // ASSERT(0);
- return false;
- }
- StdMeshers_Quadrangle_2D *quadAlgo =
- dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
- ASSERT(quadAlgo);
- try
- {
- _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace);
- // *** to delete after usage
- }
- catch(SALOME_Exception & S_ex)
- {
- // *** delete _quads
- // *** throw exception
- // ASSERT(0);
- return false;
- }
-
- // 0.2.1 - number of points on the opposite edges must be the same
- if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
- _quads[i]->nbPts[1] != _quads[i]->nbPts[3])
- {
- MESSAGE("different number of points on the opposite edges of face " << i);
- // ASSERT(0);
- return false;
- }
- }
-
- // 1. - identify faces and vertices of the "cube"
- // 1.1 - ancestor maps vertex->edges in the cube
- //MESSAGE("---");
-
- TopTools_IndexedDataMapOfShapeListOfShape MS;
- TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
-
- // 1.2 - first face is choosen as face Y=0 of the unit cube
- //MESSAGE("---");
-
- const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
- const TopoDS_Face & F = TopoDS::Face(aFace);
-
- // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
- //MESSAGE("---");
-
- int i = 0;
- TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube
- double f, l;
- Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopoDS_Vertex VFirst, VLast;
- TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
- bool isForward =
- (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+ MESSAGE("StdMeshers_Hexa_3D::Compute");
+ //bool isOk = false;
+ SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
+ //const SMESHDS_SubMesh *& subMeshDS = theSubMesh->GetSubMeshDS();
+
+ // 0. - shape and face mesh verification
+ // 0.1 - shape must be a solid (or a shell) with 6 faces
+ //MESSAGE("---");
- if (isForward)
- {
- _cube.V000 = VFirst; // will be (0,0,0) on the unit cube
- _cube.V100 = VLast; // will be (1,0,0) on the unit cube
- }
- else
- {
- _cube.V000 = VLast;
- _cube.V100 = VFirst;
- }
+ bool QuadMode = true;
- i = 1;
- E = _quads[0]->edge[i];
- C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopExp::Vertices(E, VFirst, VLast);
- isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
- if (isForward)
- _cube.V101 = VLast; // will be (1,0,1) on the unit cube
- else
- _cube.V101 = VFirst;
+ myTool = new StdMeshers_Helper(aMesh);
+ myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape,QuadMode);
- i = 2;
- E = _quads[0]->edge[i];
- C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
- TopExp::Vertices(E, VFirst, VLast);
- isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
- if (isForward)
- _cube.V001 = VLast; // will be (0,0,1) on the unit cube
- else
- _cube.V001 = VFirst;
+ vector < SMESH_subMesh * >meshFaces;
+ for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
+ SMESH_subMesh *aSubMesh = aMesh.GetSubMeshContaining(exp.Current());
+ ASSERT(aSubMesh);
+ meshFaces.push_back(aSubMesh);
+ }
+ if (meshFaces.size() != 6) {
+ SCRUTE(meshFaces.size());
+// ASSERT(0);
+ return false;
+ }
- // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
- // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
- // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0)
- // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
- //MESSAGE("---");
+ // 0.2 - is each face meshed with Quadrangle_2D? (so, with a wire of 4 edges)
+ //MESSAGE("---");
+
+ for (int i = 0; i < 6; i++) {
+ TopoDS_Shape aFace = meshFaces[i]->GetSubShape();
+ SMESH_Algo *algo = _gen->GetAlgo(aMesh, aFace);
+ string algoName = algo->GetName();
+ bool isAllQuad = false;
+ if (algoName == "Quadrangle_2D") {
+ SMESHDS_SubMesh * sm = meshDS->MeshElements( aFace );
+ if ( sm ) {
+ isAllQuad = true;
+ SMDS_ElemIteratorPtr eIt = sm->GetElements();
+ while ( isAllQuad && eIt->more() ) {
+ const SMDS_MeshElement* elem = eIt->next();
+ isAllQuad = ( elem->NbNodes()==4 ||(myCreateQuadratic && elem->NbNodes()==8) );
+ }
+ }
+ }
+ if ( ! isAllQuad ) {
+ //modified by NIZNHY-PKV Wed Nov 17 15:31:37 2004 f
+ bool bIsOk;
+ //
+ bIsOk = ComputePentahedralMesh(aMesh, aShape);
+ if (bIsOk) {
+ return true;
+ }
+ //modified by NIZNHY-PKV Wed Nov 17 15:31:42 2004 t
+ SCRUTE(algoName);
+ // ASSERT(0);
+ return false;
+ }
+ StdMeshers_Quadrangle_2D *quadAlgo =
+ dynamic_cast < StdMeshers_Quadrangle_2D * >(algo);
+ ASSERT(quadAlgo);
+ try {
+ _quads[i] = quadAlgo->CheckAnd2Dcompute(aMesh, aFace, myCreateQuadratic);
+ // add links created in quadAlgo into myNLinkNodeMap
+// NLinkNodeMap aMap = quadAlgo->GetNLinkNodeMap();
+// myNLinkNodeMap.insert(aMap.begin(), aMap.end());
+ myTool->AddNLinkNodeMap(quadAlgo->GetNLinkNodeMap());
+ // *** to delete after usage
+ }
+ catch(SALOME_Exception & S_ex) {
+ // *** delete _quads
+ // *** throw exception
+ // ASSERT(0);
+ return false;
+ }
- TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
- ASSERT(!E_0Y0.IsNull());
+ // 0.2.1 - number of points on the opposite edges must be the same
+ if (_quads[i]->nbPts[0] != _quads[i]->nbPts[2] ||
+ _quads[i]->nbPts[1] != _quads[i]->nbPts[3]) {
+ MESSAGE("different number of points on the opposite edges of face " << i);
+ // ASSERT(0);
+ return false;
+ }
+ }
- TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
- ASSERT(!E_1Y0.IsNull());
+ // 1. - identify faces and vertices of the "cube"
+ // 1.1 - ancestor maps vertex->edges in the cube
+ //MESSAGE("---");
- TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
- ASSERT(!E_1Y1.IsNull());
+ TopTools_IndexedDataMapOfShapeListOfShape MS;
+ TopExp::MapShapesAndAncestors(aShape, TopAbs_VERTEX, TopAbs_EDGE, MS);
- TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
- ASSERT(!E_0Y1.IsNull());
+ // 1.2 - first face is choosen as face Y=0 of the unit cube
+ //MESSAGE("---");
- // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
- //MESSAGE("---");
+ const TopoDS_Shape & aFace = meshFaces[0]->GetSubShape();
+ const TopoDS_Face & F = TopoDS::Face(aFace);
- TopExp::Vertices(E_0Y0, VFirst, VLast);
- if (VFirst.IsSame(_cube.V000))
- _cube.V010 = VLast;
- else
- _cube.V010 = VFirst;
+ // 1.3 - identify the 4 vertices of the face Y=0: V000, V100, V101, V001
+ //MESSAGE("---");
- TopExp::Vertices(E_1Y0, VFirst, VLast);
- if (VFirst.IsSame(_cube.V100))
- _cube.V110 = VLast;
- else
- _cube.V110 = VFirst;
+ int i = 0;
+ TopoDS_Edge E = _quads[0]->edge[i]; //edge will be Y=0,Z=0 on unit cube
+ double f, l;
+ Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopoDS_Vertex VFirst, VLast;
+ TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
+ bool isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
- TopExp::Vertices(E_1Y1, VFirst, VLast);
- if (VFirst.IsSame(_cube.V101))
- _cube.V111 = VLast;
- else
- _cube.V111 = VFirst;
+ if (isForward) {
+ _cube.V000 = VFirst; // will be (0,0,0) on the unit cube
+ _cube.V100 = VLast; // will be (1,0,0) on the unit cube
+ }
+ else {
+ _cube.V000 = VLast;
+ _cube.V100 = VFirst;
+ }
- TopExp::Vertices(E_0Y1, VFirst, VLast);
- if (VFirst.IsSame(_cube.V001))
- _cube.V011 = VLast;
- else
- _cube.V011 = VFirst;
-
- // 1.6 - find remaining faces given 4 vertices
- //MESSAGE("---");
-
- _indY0 = 0;
- _cube.quad_Y0 = _quads[_indY0];
-
- _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
- _cube.V010, _cube.V011, _cube.V110, _cube.V111);
- _cube.quad_Y1 = _quads[_indY1];
-
- _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
- _cube.V000, _cube.V010, _cube.V100, _cube.V110);
- _cube.quad_Z0 = _quads[_indZ0];
-
- _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
- _cube.V001, _cube.V011, _cube.V101, _cube.V111);
- _cube.quad_Z1 = _quads[_indZ1];
-
- _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
- _cube.V000, _cube.V001, _cube.V010, _cube.V011);
- _cube.quad_X0 = _quads[_indX0];
-
- _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
- _cube.V100, _cube.V101, _cube.V110, _cube.V111);
- _cube.quad_X1 = _quads[_indX1];
-
- //MESSAGE("---");
-
- // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
-
- Conv2DStruct cx0; // for face X=0
- Conv2DStruct cx1; // for face X=1
- Conv2DStruct cy0;
- Conv2DStruct cy1;
- Conv2DStruct cz0;
- Conv2DStruct cz1;
-
- GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
- _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
- GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
- _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
- GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
- _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
- GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
- _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
- GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
- _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
- GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
- _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
-
- // 1.8 - create a 3D structure for normalized values
-
- //MESSAGE("---");
- int nbx = _cube.quad_Z0->nbPts[0];
- if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1];
+ i = 1;
+ E = _quads[0]->edge[i];
+ C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopExp::Vertices(E, VFirst, VLast);
+ isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+ if (isForward)
+ _cube.V101 = VLast; // will be (1,0,1) on the unit cube
+ else
+ _cube.V101 = VFirst;
+
+ i = 2;
+ E = _quads[0]->edge[i];
+ C2d = BRep_Tool::CurveOnSurface(E, F, f, l);
+ TopExp::Vertices(E, VFirst, VLast);
+ isForward = (((l - f) * (_quads[0]->last[i] - _quads[0]->first[i])) > 0);
+ if (isForward)
+ _cube.V001 = VLast; // will be (0,0,1) on the unit cube
+ else
+ _cube.V001 = VFirst;
+
+ // 1.4 - find edge X=0, Z=0 (ancestor of V000 not in face Y=0)
+ // - find edge X=1, Z=0 (ancestor of V100 not in face Y=0)
+ // - find edge X=1, Z=1 (ancestor of V101 not in face Y=0)
+ // - find edge X=0, Z=1 (ancestor of V001 not in face Y=0)
+ //MESSAGE("---");
+
+ TopoDS_Edge E_0Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V000, MS);
+ ASSERT(!E_0Y0.IsNull());
+
+ TopoDS_Edge E_1Y0 = EdgeNotInFace(aMesh, aShape, F, _cube.V100, MS);
+ ASSERT(!E_1Y0.IsNull());
+
+ TopoDS_Edge E_1Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V101, MS);
+ ASSERT(!E_1Y1.IsNull());
+
+ TopoDS_Edge E_0Y1 = EdgeNotInFace(aMesh, aShape, F, _cube.V001, MS);
+ ASSERT(!E_0Y1.IsNull());
+
+ // 1.5 - identify the 4 vertices in face Y=1: V010, V110, V111, V011
+ //MESSAGE("---");
+
+ TopExp::Vertices(E_0Y0, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V000))
+ _cube.V010 = VLast;
+ else
+ _cube.V010 = VFirst;
+
+ TopExp::Vertices(E_1Y0, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V100))
+ _cube.V110 = VLast;
+ else
+ _cube.V110 = VFirst;
+
+ TopExp::Vertices(E_1Y1, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V101))
+ _cube.V111 = VLast;
+ else
+ _cube.V111 = VFirst;
+
+ TopExp::Vertices(E_0Y1, VFirst, VLast);
+ if (VFirst.IsSame(_cube.V001))
+ _cube.V011 = VLast;
+ else
+ _cube.V011 = VFirst;
+
+ // 1.6 - find remaining faces given 4 vertices
+ //MESSAGE("---");
+
+ _indY0 = 0;
+ _cube.quad_Y0 = _quads[_indY0];
+
+ _indY1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V010, _cube.V011, _cube.V110, _cube.V111);
+ _cube.quad_Y1 = _quads[_indY1];
+
+ _indZ0 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V000, _cube.V010, _cube.V100, _cube.V110);
+ _cube.quad_Z0 = _quads[_indZ0];
+
+ _indZ1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V001, _cube.V011, _cube.V101, _cube.V111);
+ _cube.quad_Z1 = _quads[_indZ1];
+
+ _indX0 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V000, _cube.V001, _cube.V010, _cube.V011);
+ _cube.quad_X0 = _quads[_indX0];
+
+ _indX1 = GetFaceIndex(aMesh, aShape, meshFaces,
+ _cube.V100, _cube.V101, _cube.V110, _cube.V111);
+ _cube.quad_X1 = _quads[_indX1];
+
+ //MESSAGE("---");
+
+ // 1.7 - get convertion coefs from face 2D normalized to 3D normalized
+
+ Conv2DStruct cx0; // for face X=0
+ Conv2DStruct cx1; // for face X=1
+ Conv2DStruct cy0;
+ Conv2DStruct cy1;
+ Conv2DStruct cz0;
+ Conv2DStruct cz1;
+
+ GetConv2DCoefs(*_cube.quad_X0, meshFaces[_indX0]->GetSubShape(),
+ _cube.V000, _cube.V010, _cube.V011, _cube.V001, cx0);
+ GetConv2DCoefs(*_cube.quad_X1, meshFaces[_indX1]->GetSubShape(),
+ _cube.V100, _cube.V110, _cube.V111, _cube.V101, cx1);
+ GetConv2DCoefs(*_cube.quad_Y0, meshFaces[_indY0]->GetSubShape(),
+ _cube.V000, _cube.V100, _cube.V101, _cube.V001, cy0);
+ GetConv2DCoefs(*_cube.quad_Y1, meshFaces[_indY1]->GetSubShape(),
+ _cube.V010, _cube.V110, _cube.V111, _cube.V011, cy1);
+ GetConv2DCoefs(*_cube.quad_Z0, meshFaces[_indZ0]->GetSubShape(),
+ _cube.V000, _cube.V100, _cube.V110, _cube.V010, cz0);
+ GetConv2DCoefs(*_cube.quad_Z1, meshFaces[_indZ1]->GetSubShape(),
+ _cube.V001, _cube.V101, _cube.V111, _cube.V011, cz1);
+
+ // 1.8 - create a 3D structure for normalized values
+
+ //MESSAGE("---");
+ int nbx = _cube.quad_Z0->nbPts[0];
+ if (cz0.a1 == 0.) nbx = _cube.quad_Z0->nbPts[1];
- int nby = _cube.quad_X0->nbPts[0];
- if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1];
+ int nby = _cube.quad_X0->nbPts[0];
+ if (cx0.a1 == 0.) nby = _cube.quad_X0->nbPts[1];
- int nbz = _cube.quad_Y0->nbPts[0];
- if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1];
-
- int i1, j1, nbxyz = nbx * nby * nbz;
- Point3DStruct *np = new Point3DStruct[nbxyz];
+ int nbz = _cube.quad_Y0->nbPts[0];
+ if (cy0.a1 != 0.) nbz = _cube.quad_Y0->nbPts[1];
- // 1.9 - store node indexes of faces
+ int i1, j1, nbxyz = nbx * nby * nbz;
+ Point3DStruct *np = new Point3DStruct[nbxyz];
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
+ // 1.9 - store node indexes of faces
- faceQuadStruct *quad = _cube.quad_X0;
- int i = 0; // j = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX0]->GetSubShape());
+ faceQuadStruct *quad = _cube.quad_X0;
+ int i = 0; // j = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
-
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face
- int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
-
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
-
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- faceQuadStruct *quad = _cube.quad_X1;
- int i = nbx - 1; // j = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int j = cx0.ia * i1 + cx0.ib * j1 + cx0.ic; // j = x/face
+ int k = cx0.ja * i1 + cx0.jb * j1 + cx0.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indX1]->GetSubShape());
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face
- int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
+ faceQuadStruct *quad = _cube.quad_X1;
+ int i = nbx - 1; // j = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- faceQuadStruct *quad = _cube.quad_Y0;
- int j = 0; // i = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int j = cx1.ia * i1 + cx1.ib * j1 + cx1.ic; // j = x/face
+ int k = cx1.ja * i1 + cx1.jb * j1 + cx1.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY0]->GetSubShape());
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face
- int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
+ faceQuadStruct *quad = _cube.quad_Y0;
+ int j = 0; // i = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- faceQuadStruct *quad = _cube.quad_Y1;
- int j = nby - 1; // i = x/face , k = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int i = cy0.ia * i1 + cy0.ib * j1 + cy0.ic; // i = x/face
+ int k = cy0.ja * i1 + cy0.jb * j1 + cy0.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indY1]->GetSubShape());
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face
- int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
+ faceQuadStruct *quad = _cube.quad_Y1;
+ int j = nby - 1; // i = x/face , k = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- faceQuadStruct *quad = _cube.quad_Z0;
- int k = 0; // i = x/face , j = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int i = cy1.ia * i1 + cy1.ib * j1 + cy1.ic; // i = x/face
+ int k = cy1.ja * i1 + cy1.jb * j1 + cy1.jc; // k = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ0]->GetSubShape());
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face
- int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
- {
- const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
+ faceQuadStruct *quad = _cube.quad_Z0;
+ int k = 0; // i = x/face , j = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
- SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- faceQuadStruct *quad = _cube.quad_Z1;
- int k = nbz - 1; // i = x/face , j = y/face
- int nbdown = quad->nbPts[0];
- int nbright = quad->nbPts[1];
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int i = cz0.ia * i1 + cz0.ib * j1 + cz0.ic; // i = x/face
+ int j = cz0.ja * i1 + cz0.jb * j1 + cz0.jc; // j = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- while(itf->more())
- {
- const SMDS_MeshNode * node = itf->next();
- findIJ( node, quad, i1, j1 );
- int ij1 = j1 * nbdown + i1;
- quad->uv_grid[ij1].node = node;
- }
+ {
+ const TopoDS_Face & F = TopoDS::Face(meshFaces[_indZ1]->GetSubShape());
+
+ SMDS_NodeIteratorPtr itf= aMesh.GetSubMesh(F)->GetSubMeshDS()->GetNodes();
+
+ faceQuadStruct *quad = _cube.quad_Z1;
+ int k = nbz - 1; // i = x/face , j = y/face
+ int nbdown = quad->nbPts[0];
+ int nbright = quad->nbPts[1];
+
+ while(itf->more()) {
+ const SMDS_MeshNode * node = itf->next();
+ if(myTool->IsMedium(node))
+ continue;
+ findIJ( node, quad, i1, j1 );
+ int ij1 = j1 * nbdown + i1;
+ quad->uv_grid[ij1].node = node;
+ }
- for (int i1 = 0; i1 < nbdown; i1++)
- for (int j1 = 0; j1 < nbright; j1++)
- {
- int ij1 = j1 * nbdown + i1;
- int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face
- int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face
- int ijk = k * nbx * nby + j * nbx + i;
- //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
- np[ijk].node = quad->uv_grid[ij1].node;
- //SCRUTE(np[ijk].nodeId);
- }
- }
+ for (int i1 = 0; i1 < nbdown; i1++)
+ for (int j1 = 0; j1 < nbright; j1++) {
+ int ij1 = j1 * nbdown + i1;
+ int i = cz1.ia * i1 + cz1.ib * j1 + cz1.ic; // i = x/face
+ int j = cz1.ja * i1 + cz1.jb * j1 + cz1.jc; // j = y/face
+ int ijk = k * nbx * nby + j * nbx + i;
+ //MESSAGE(" "<<ij1<<" "<<i<<" "<<j<<" "<<ijk);
+ np[ijk].node = quad->uv_grid[ij1].node;
+ //SCRUTE(np[ijk].nodeId);
+ }
+ }
- // 2.0 - for each node of the cube:
- // - get the 8 points 3D = 8 vertices of the cube
- // - get the 12 points 3D on the 12 edges of the cube
- // - get the 6 points 3D on the 6 faces with their ID
- // - compute the point 3D
- // - store the point 3D in SMESHDS, store its ID in 3D structure
-
- int shapeID = meshDS->ShapeToIndex( aShape );
-
- Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
- Pt3 px00, px01, px10, px11;
- Pt3 p0y0, p0y1, p1y0, p1y1;
- Pt3 p00z, p01z, p10z, p11z;
- Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
-
- GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
-
- for (int i = 1; i < nbx - 1; i++)
- {
- for (int j = 1; j < nby - 1; j++)
- {
- for (int k = 1; k < nbz - 1; k++)
- {
- // *** seulement maillage regulier
- // 12 points on edges
- GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
-
- GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
-
- GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
- GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
- GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
- GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
-
- // 12 points on faces
- GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
- GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
- GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
- GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
- GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
- GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
-
- int ijk = k * nbx * nby + j * nbx + i;
- double x = double (i) / double (nbx - 1); // *** seulement
- double y = double (j) / double (nby - 1); // *** maillage
- double z = double (k) / double (nbz - 1); // *** regulier
-
- Pt3 X;
- for (int i = 0; i < 3; i++)
- {
- X[i] =
- (1 - x) * p0yz[i] + x * p1yz[i]
- + (1 - y) * px0z[i] + y * px1z[i]
- + (1 - z) * pxy0[i] + z * pxy1[i]
- - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
- - x * ((1 - y) * p10z[i] + y * p11z[i])
- - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
- - y * ((1 - z) * px10[i] + z * px11[i])
- - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
- - z * ((1 - x) * p0y1[i] + x * p1y1[i])
- + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
- + y * ((1 - z) * p010[i] + z * p011[i]))
- + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
- + y * ((1 - z) * p110[i] + z * p111[i]));
- }
-
- SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
- np[ijk].node = node;
- meshDS->SetNodeInVolume(node, shapeID);
- }
- }
- }
+ // 2.0 - for each node of the cube:
+ // - get the 8 points 3D = 8 vertices of the cube
+ // - get the 12 points 3D on the 12 edges of the cube
+ // - get the 6 points 3D on the 6 faces with their ID
+ // - compute the point 3D
+ // - store the point 3D in SMESHDS, store its ID in 3D structure
+
+ int shapeID = meshDS->ShapeToIndex( aShape );
+
+ Pt3 p000, p001, p010, p011, p100, p101, p110, p111;
+ Pt3 px00, px01, px10, px11;
+ Pt3 p0y0, p0y1, p1y0, p1y1;
+ Pt3 p00z, p01z, p10z, p11z;
+ Pt3 pxy0, pxy1, px0z, px1z, p0yz, p1yz;
+
+ GetPoint(p000, 0, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p001, 0, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p010, 0, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p011, 0, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p100, nbx - 1, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p101, nbx - 1, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p110, nbx - 1, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p111, nbx - 1, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ for (int i = 1; i < nbx - 1; i++) {
+ for (int j = 1; j < nby - 1; j++) {
+ for (int k = 1; k < nbz - 1; k++) {
+ // *** seulement maillage regulier
+ // 12 points on edges
+ GetPoint(px00, i, 0, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(px01, i, 0, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(px10, i, nby - 1, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(px11, i, nby - 1, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ GetPoint(p0y0, 0, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p0y1, 0, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1y0, nbx - 1, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1y1, nbx - 1, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+
+ GetPoint(p00z, 0, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p01z, 0, nby - 1, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p10z, nbx - 1, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p11z, nbx - 1, nby - 1, k, nbx, nby, nbz, np, meshDS);
+
+ // 12 points on faces
+ GetPoint(pxy0, i, j, 0, nbx, nby, nbz, np, meshDS);
+ GetPoint(pxy1, i, j, nbz - 1, nbx, nby, nbz, np, meshDS);
+ GetPoint(px0z, i, 0, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(px1z, i, nby - 1, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p0yz, 0, j, k, nbx, nby, nbz, np, meshDS);
+ GetPoint(p1yz, nbx - 1, j, k, nbx, nby, nbz, np, meshDS);
+
+ int ijk = k * nbx * nby + j * nbx + i;
+ double x = double (i) / double (nbx - 1); // *** seulement
+ double y = double (j) / double (nby - 1); // *** maillage
+ double z = double (k) / double (nbz - 1); // *** regulier
+
+ Pt3 X;
+ for (int i = 0; i < 3; i++) {
+ X[i] = (1 - x) * p0yz[i] + x * p1yz[i]
+ + (1 - y) * px0z[i] + y * px1z[i]
+ + (1 - z) * pxy0[i] + z * pxy1[i]
+ - (1 - x) * ((1 - y) * p00z[i] + y * p01z[i])
+ - x * ((1 - y) * p10z[i] + y * p11z[i])
+ - (1 - y) * ((1 - z) * px00[i] + z * px01[i])
+ - y * ((1 - z) * px10[i] + z * px11[i])
+ - (1 - z) * ((1 - x) * p0y0[i] + x * p1y0[i])
+ - z * ((1 - x) * p0y1[i] + x * p1y1[i])
+ + (1 - x) * ((1 - y) * ((1 - z) * p000[i] + z * p001[i])
+ + y * ((1 - z) * p010[i] + z * p011[i]))
+ + x * ((1 - y) * ((1 - z) * p100[i] + z * p101[i])
+ + y * ((1 - z) * p110[i] + z * p111[i]));
+ }
+
+ SMDS_MeshNode * node = meshDS->AddNode(X[0], X[1], X[2]);
+ np[ijk].node = node;
+ meshDS->SetNodeInVolume(node, shapeID);
+ }
+ }
+ }
// find orientation of furute volumes according to MED convention
vector< bool > forward( nbx * nby );
SMDS_VolumeTool vTool;
- for (int i = 0; i < nbx - 1; i++)
- for (int j = 0; j < nby - 1; j++)
- {
+ for (int i = 0; i < nbx - 1; i++) {
+ for (int j = 0; j < nby - 1; j++) {
int n1 = j * nbx + i;
int n2 = j * nbx + i + 1;
int n3 = (j + 1) * nbx + i + 1;
vTool.Set( &tmpVol );
forward[ n1 ] = vTool.IsForward();
}
+ }
- //2.1 - for each node of the cube (less 3 *1 Faces):
- // - store hexahedron in SMESHDS
- MESSAGE("Storing hexahedron into the DS");
- for (int i = 0; i < nbx - 1; i++)
- for (int j = 0; j < nby - 1; j++)
- {
- bool isForw = forward.at( j * nbx + i );
- for (int k = 0; k < nbz - 1; k++)
- {
- int n1 = k * nbx * nby + j * nbx + i;
- int n2 = k * nbx * nby + j * nbx + i + 1;
- int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
- int n4 = k * nbx * nby + (j + 1) * nbx + i;
- int n5 = (k + 1) * nbx * nby + j * nbx + i;
- int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
- int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
- int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
-
- SMDS_MeshVolume * elt;
- if ( isForw )
- elt = meshDS->AddVolume(np[n1].node,
- np[n2].node,
- np[n3].node,
- np[n4].node,
- np[n5].node,
- np[n6].node,
- np[n7].node,
- np[n8].node);
- else
- elt = meshDS->AddVolume(np[n1].node,
- np[n4].node,
- np[n3].node,
- np[n2].node,
- np[n5].node,
- np[n8].node,
- np[n7].node,
- np[n6].node);
-
- meshDS->SetMeshElementOnShape(elt, shapeID);
- }
- }
+ //2.1 - for each node of the cube (less 3 *1 Faces):
+ // - store hexahedron in SMESHDS
+ MESSAGE("Storing hexahedron into the DS");
+ for (int i = 0; i < nbx - 1; i++) {
+ for (int j = 0; j < nby - 1; j++) {
+ bool isForw = forward.at( j * nbx + i );
+ for (int k = 0; k < nbz - 1; k++) {
+ int n1 = k * nbx * nby + j * nbx + i;
+ int n2 = k * nbx * nby + j * nbx + i + 1;
+ int n3 = k * nbx * nby + (j + 1) * nbx + i + 1;
+ int n4 = k * nbx * nby + (j + 1) * nbx + i;
+ int n5 = (k + 1) * nbx * nby + j * nbx + i;
+ int n6 = (k + 1) * nbx * nby + j * nbx + i + 1;
+ int n7 = (k + 1) * nbx * nby + (j + 1) * nbx + i + 1;
+ int n8 = (k + 1) * nbx * nby + (j + 1) * nbx + i;
+
+ SMDS_MeshVolume * elt;
+ if ( isForw ) {
+ //elt = meshDS->AddVolume(np[n1].node, np[n2].node,
+ // np[n3].node, np[n4].node,
+ // np[n5].node, np[n6].node,
+ // np[n7].node, np[n8].node);
+ elt = myTool->AddVolume(np[n1].node, np[n2].node,
+ np[n3].node, np[n4].node,
+ np[n5].node, np[n6].node,
+ np[n7].node, np[n8].node);
+ }
+ else {
+ //elt = meshDS->AddVolume(np[n1].node, np[n4].node,
+ // np[n3].node, np[n2].node,
+ // np[n5].node, np[n8].node,
+ // np[n7].node, np[n6].node);
+ elt = myTool->AddVolume(np[n1].node, np[n4].node,
+ np[n3].node, np[n2].node,
+ np[n5].node, np[n8].node,
+ np[n7].node, np[n6].node);
+ }
+
+ meshDS->SetMeshElementOnShape(elt, shapeID);
+ }
+ }
+ }
if ( np ) delete [] np;
- //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
- return true;
+ //MESSAGE("End of StdMeshers_Hexa_3D::Compute()");
+ return true;
}
//=============================================================================
return bOK;
}
+
#include "StdMeshers_Quadrangle_2D.hxx"
#include "Utils_SALOME_Exception.hxx"
+#include "StdMeshers_Helper.hxx"
+
typedef struct point3Dstruct
{
const SMDS_MeshNode * node;
int _indY1;
int _indZ0;
int _indZ1;
+
+ bool myCreateQuadratic;
+ StdMeshers_Helper* myTool; // toll for working with quadratic elements
};
#endif
bool StdMeshers_MEFISTO_2D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
- MESSAGE("StdMeshers_MEFISTO_2D::Compute");
+ MESSAGE("StdMeshers_MEFISTO_2D::Compute");
- if (_hypLengthFromEdges)
- _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+ if (_hypLengthFromEdges)
+ _edgeLength = ComputeEdgeElementLength(aMesh, aShape);
+
+ bool isOk = false;
+ //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
- bool isOk = false;
- //const SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
- //SMESH_subMesh *theSubMesh = aMesh.GetSubMesh(aShape);
-
- const TopoDS_Face & FF = TopoDS::Face(aShape);
- bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
- TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
-
- Z nblf; //nombre de lignes fermees (enveloppe en tete)
- Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
- R2 *uvslf = NULL;
- Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
- R2 *uvpti = NULL;
-
- Z nbst;
- R2 *uvst = NULL;
- Z nbt;
- Z *nust = NULL;
- Z ierr = 0;
-
- Z nutysu = 1; // 1: il existe un fonction areteideale_()
- // Z nutysu=0; // 0: on utilise aretmx
- R aretmx = _edgeLength; // longueur max aretes future triangulation
-
- nblf = NumberOfWires(F);
-
- nudslf = new Z[1 + nblf];
- nudslf[0] = 0;
- int iw = 1;
- int nbpnt = 0;
-
- myOuterWire = BRepTools::OuterWire(F);
- nbpnt += NumberOfPoints(aMesh, myOuterWire);
- if ( nbpnt < 3 ) // ex: a circle with 2 segments
- return false;
- nudslf[iw++] = nbpnt;
+ const TopoDS_Face & FF = TopoDS::Face(aShape);
+ bool faceIsForward = (FF.Orientation() == TopAbs_FORWARD);
+ TopoDS_Face F = TopoDS::Face(FF.Oriented(TopAbs_FORWARD));
- for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
- {
- const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
- if (!myOuterWire.IsSame(W))
- {
- nbpnt += NumberOfPoints(aMesh, W);
- nudslf[iw++] = nbpnt;
- }
- }
+ Z nblf; //nombre de lignes fermees (enveloppe en tete)
+ Z *nudslf = NULL; //numero du dernier sommet de chaque ligne fermee
+ R2 *uvslf = NULL;
+ Z nbpti = 0; //nombre points internes futurs sommets de la triangulation
+ R2 *uvpti = NULL;
+
+ Z nbst;
+ R2 *uvst = NULL;
+ Z nbt;
+ Z *nust = NULL;
+ Z ierr = 0;
+
+ Z nutysu = 1; // 1: il existe un fonction areteideale_()
+ // Z nutysu=0; // 0: on utilise aretmx
+ R aretmx = _edgeLength; // longueur max aretes future triangulation
+
+ nblf = NumberOfWires(F);
+
+ nudslf = new Z[1 + nblf];
+ nudslf[0] = 0;
+ int iw = 1;
+ int nbpnt = 0;
+
+ bool QuadMode = true;
+
+ myTool = new StdMeshers_Helper(aMesh);
+ myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape,QuadMode);
+
+ myOuterWire = BRepTools::OuterWire(F);
+ nbpnt += NumberOfPoints(aMesh, myOuterWire);
+ if ( nbpnt < 3 ) // ex: a circle with 2 segments
+ return false;
+ nudslf[iw++] = nbpnt;
+
+ for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next()) {
+ const TopoDS_Wire & W = TopoDS::Wire(exp.Current());
+ if (!myOuterWire.IsSame(W)) {
+ nbpnt += NumberOfPoints(aMesh, W);
+ nudslf[iw++] = nbpnt;
+ }
+ }
- // avoid passing same uv points for a vertex common to 2 wires
- TopTools_IndexedDataMapOfShapeListOfShape VWMap;
- if ( iw - 1 > 1 ) // nbofWires > 1
- TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
+ // avoid passing same uv points for a vertex common to 2 wires
+ TopTools_IndexedDataMapOfShapeListOfShape VWMap;
+ if ( iw - 1 > 1 ) // nbofWires > 1
+ TopExp::MapShapesAndAncestors( F , TopAbs_VERTEX, TopAbs_WIRE, VWMap );
- uvslf = new R2[nudslf[nblf]];
- int m = 0;
+ uvslf = new R2[nudslf[nblf]];
+ int m = 0;
- double scalex, scaley;
- ComputeScaleOnFace(aMesh, F, scalex, scaley);
+ double scalex, scaley;
+ ComputeScaleOnFace(aMesh, F, scalex, scaley);
- map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
- if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
- mefistoToDS, scalex, scaley, VWMap))
- return false;
+ map<int, const SMDS_MeshNode*> mefistoToDS; // correspondence mefisto index--> points IDNodes
+ if ( !LoadPoints(aMesh, F, myOuterWire, uvslf, m,
+ mefistoToDS, scalex, scaley, VWMap) )
+ return false;
for (TopExp_Explorer exp(F, TopAbs_WIRE); exp.More(); exp.Next())
{
const TopoDS_Wire& theOW,
const TopoDS_Face& theF,
const TopTools_IndexedDataMapOfShapeListOfShape & theVWMap,
- SMESH_Mesh & theMesh)
+ SMESH_Mesh & theMesh,
+ bool CreateQuadratic)
{
if( theW.IsSame( theOW ) ||
!theVWMap.Contains( theV )) return false;
umin = l;
umax = f;
}
- else
- {
+ else {
while ( nIt->more() ) {
const SMDS_MeshNode* node = nIt->next();
+ if(CreateQuadratic) {
+ // check if node is medium
+ bool IsMedium = false;
+ SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+ while (itn->more()) {
+ const SMDS_MeshElement* elem = itn->next();
+ if ( elem->GetType() != SMDSAbs_Edge )
+ continue;
+ if(elem->IsMediumNode(node)) {
+ IsMedium = true;
+ break;
+ }
+ }
+ if(IsMedium)
+ continue;
+ }
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
double u = epos->GetUParameter();
TopoDS_Wire W = TopoDS::Wire(WW.Oriented(TopAbs_FORWARD));
BRepTools_WireExplorer wexp(W, F);
- for (wexp.Init(W, F), iEdge = 0; wexp.More(); wexp.Next(), iEdge++)
- {
+ for (wexp.Init(W, F), iEdge = 0; wexp.More(); wexp.Next(), iEdge++) {
const TopoDS_Edge & E = wexp.Current();
// --- IDNodes of first and last Vertex
TopExp::Vertices(E, VFirst, VLast); // corresponds to f and l
ASSERT(!VFirst.IsNull());
- SMDS_NodeIteratorPtr lid=
+ SMDS_NodeIteratorPtr lid =
aMesh.GetSubMesh(VFirst)->GetSubMeshDS()->GetNodes();
if ( !lid->more() ) {
MESSAGE (" NO NODE BUILT ON VERTEX ");
const SMDS_MeshNode* idFirst = lid->next();
ASSERT(!VLast.IsNull());
- lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
+ lid = aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
if ( !lid->more() ) {
MESSAGE (" NO NODE BUILT ON VERTEX ");
return false;
// --- edge internal IDNodes (relies on good order storage, not checked)
+// if(myCreateQuadratic) {
+ // fill myNLinkNodeMap
+// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
+// while(iter->more()) {
+// const SMDS_MeshElement* elem = iter->next();
+// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+// const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
+// myNLinkNodeMap[link] = n3;
+// }
+// }
+
int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
double f, l;
//bool isForward = (E.Orientation() == TopAbs_FORWARD);
map<double, const SMDS_MeshNode*> params;
- while(ite->more())
- {
- const SMDS_MeshNode * node = ite->next();
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
+ if(!myCreateQuadratic) {
+ while(ite->more()) {
+ const SMDS_MeshNode * node = ite->next();
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
}
- if ( nbPoints != params.size())
- {
+ else {
+ nbPoints = nbPoints/2;
+ while(ite->more()) {
+ const SMDS_MeshNode* node = ite->next();
+ // check if node is medium
+ bool IsMedium = false;
+ SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+ while (itn->more()) {
+ const SMDS_MeshElement* elem = itn->next();
+ if ( elem->GetType() != SMDSAbs_Edge )
+ continue;
+ if(elem->IsMediumNode(node)) {
+ IsMedium = true;
+ break;
+ }
+ }
+ if(IsMedium)
+ continue;
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
+ }
+
+ if ( nbPoints != params.size()) {
MESSAGE( "BAD NODE ON EDGE POSITIONS" );
return false;
}
// --- load 2D values into MEFISTO structure,
// add IDNodes in mefistoToDS map
- if (E.Orientation() == TopAbs_FORWARD)
- {
+ if (E.Orientation() == TopAbs_FORWARD) {
gp_Pnt2d p = C2d->Value(f).XY().Multiplied( scale ); // first point = Vertex Forward
- if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh ))
+ if ( fixCommonVertexUV( p, VFirst, W, myOuterWire, F, VWMap, aMesh, myCreateQuadratic ))
myNodesOnCommonV.push_back( idFirst );
uvslf[m].x = p.X();
uvslf[m].y = p.Y();
//MESSAGE("__ f "<<f<<" "<<uvslf[m].x <<" "<<uvslf[m].y);
m++;
map<double, const SMDS_MeshNode*>::iterator itp = params.begin();
- for (int i = 1; i <= nbPoints; i++) // nbPoints internal
- {
+ for (int i = 1; i <= nbPoints; i++) { // nbPoints internal
double param = (*itp).first;
gp_Pnt2d p = C2d->Value(param).XY().Multiplied( scale );
uvslf[m].x = p.X();
itp++;
}
}
- else
- {
+ else {
gp_Pnt2d p = C2d->Value(l).XY().Multiplied( scale ); // last point = Vertex Reversed
- if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh ))
+ if ( fixCommonVertexUV( p, VLast, W, myOuterWire, F, VWMap, aMesh, myCreateQuadratic ))
myNodesOnCommonV.push_back( idLast );
uvslf[m].x = p.X();
uvslf[m].y = p.Y();
SMDS_MeshElement * elt;
if (triangleIsWellOriented)
- elt = meshDS->AddFace(n1, n2, n3);
+ //elt = meshDS->AddFace(n1, n2, n3);
+ elt = myTool->AddFace(n1, n2, n3);
else
- elt = meshDS->AddFace(n1, n3, n2);
+ //elt = meshDS->AddFace(n1, n3, n2);
+ elt = myTool->AddFace(n1, n3, n2);
meshDS->SetMeshElementOnShape(elt, faceID);
m++;
#include "SMESH_2D_Algo.hxx"
#include <TopoDS_Wire.hxx>
+#include "StdMeshers_Helper.hxx"
+
class SMDS_MeshNode;
class TopTools_IndexedDataMapOfShapeListOfShape;
class TopoDS_Face;
TopoDS_Wire myOuterWire;
std::list<const SMDS_MeshNode*> myNodesOnCommonV;
+
+ StdMeshers_Helper* myTool; // toll for working with quadratic elements
};
#endif
#include <TopoDS_Shell.hxx>
#include <TopoDS_Vertex.hxx>
#include <gp_Pnt.hxx>
+#include <BRepTools.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <TopTools_MapOfShape.hxx>
#include <stdio.h>
#include <algorithm>
myWallNodesMaps.resize( SMESH_Block::NbFaces() );
myShapeXYZ.resize( SMESH_Block::NbSubShapes() );
}
+
+
//=======================================================================
//function : Compute
//purpose :
if (myErrorStatus){
return bOK;
}
+
+ bool QuadMode = true;
+
+ myTool = new StdMeshers_Helper(aMesh);
+ myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape,QuadMode);
+
//
MakeBlock();
- if (myErrorStatus){
+ if (myErrorStatus){
+ return bOK;
+ }
+ //
+ ClearMeshOnFxy1();
+ if (myErrorStatus) {
return bOK;
}
//
//
MakeConnectingMap();
//
- ClearMeshOnFxy1();
- if (myErrorStatus) {
- return bOK;
- }
- //
MakeMeshOnFxy1();
if (myErrorStatus) {
return bOK;
//
return !bOK;
}
+
//=======================================================================
//function : MakeNodes
//purpose :
// 1.1 Horizontal size
myJSize=0;
for (i=0; i<aNbSIDs; ++i) {
- const TopoDS_Shape& aS=myBlock.Shape(aSIDs[i]);
+ const TopoDS_Shape& aS = myBlock.Shape(aSIDs[i]);
SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
ASSERT(aSubMesh);
- SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
- iNbN=aSM->NbNodes();
- myJSize+=iNbN;
+ SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+ if(!myCreateQuadratic) {
+ iNbN = aSM->NbNodes();
+ }
+ else {
+ iNbN = 0;
+ SMDS_NodeIteratorPtr itn = aSM->GetNodes();
+ while(itn->more()) {
+ const SMDS_MeshNode* aNode = itn->next();
+ if(myTool->IsMedium(aNode))
+ continue;
+ iNbN++;
+ }
+ }
+ myJSize += iNbN;
}
//printf("*** Horizontal: number of nodes summary=%d\n", myJSize);
//
const TopoDS_Shape& aS=myBlock.Shape(SMESH_Block::ID_E00z);
SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aS);
ASSERT(aSubMesh);
- SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
- iNbN=aSM->NbNodes();
- myISize+=iNbN;
+ SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+ if(!myCreateQuadratic) {
+ iNbN = aSM->NbNodes();
+ }
+ else {
+ iNbN = 0;
+ SMDS_NodeIteratorPtr itn = aSM->GetNodes();
+ while(itn->more()) {
+ const SMDS_MeshNode* aNode = itn->next();
+ if(myTool->IsMedium(aNode))
+ continue;
+ iNbN++;
+ }
+ }
+ myISize += iNbN;
}
//printf("*** Vertical: number of nodes on edges and vertices=%d\n", myISize);
//
// vertices
for (k=0; k<aNbSIDs; ++k) {
aSID=aSIDs[k];
- const TopoDS_Shape& aS=myBlock.Shape(aSID);
- SMDS_NodeIteratorPtr ite =pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
+ const TopoDS_Shape& aS = myBlock.Shape(aSID);
+ SMDS_NodeIteratorPtr ite = pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
while(ite->more()) {
const SMDS_MeshNode* aNode = ite->next();
+ if(myTool->IsMedium(aNode))
+ continue;
aNodeID=aNode->GetID();
//
aTNode.SetNode(aNode);
aTNode.SetShapeSupportID(aSID);
aTNode.SetBaseNodeID(aNodeID);
//
- if ( SMESH_Block::IsEdgeID (aSID))
- {
+ if ( SMESH_Block::IsEdgeID (aSID)) {
const SMDS_EdgePosition* epos =
static_cast<const SMDS_EdgePosition*>(aNode->GetPosition().get());
myBlock.ComputeParameters( epos->GetUParameter(), aS, aCoords );
aP3D.SetCoord(aX, aY, aZ);
myBlock.ComputeParameters(aP3D, aS, aCoords);
}
- iErr=myBlock.ErrorStatus();
+ iErr = myBlock.ErrorStatus();
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes()," <<
"SMESHBlock: ComputeParameters operation failed");
// 3.3 set XYZ of vertices, and initialize of the rest
SMESHDS_Mesh* aMesh = GetMesh()->GetMeshDS();
- for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id )
- {
+ for ( int id = SMESH_Block::ID_V000; id < SMESH_Block::ID_Shell; ++id ) {
if ( SMESH_Block::IsVertexID( id )) {
TopoDS_Shape V = myBlock.Shape( id );
SMESHDS_SubMesh* sm = aMesh->MeshElements( V );
SMESH_Block::TShapeID aSSID, aBNSSID;
StdMeshers_TNode aTN;
//
- for (j=0; j<myJSize; ++j)
- {
+
+ // create top face and find UV for it's corners
+ const TopoDS_Face& TopFace = TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
+ SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
+ int topfaceID = meshDS->ShapeToIndex(TopFace);
+ const TopoDS_Vertex& v001 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V001));
+ SMDS_NodeIteratorPtr itn = pMesh->GetSubMeshContaining(v001)->GetSubMeshDS()->GetNodes();
+ const SMDS_MeshNode* N = itn->next();
+ gp_XY UV001 = myTool->GetNodeUV(TopFace,N);
+ const TopoDS_Vertex& v101 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V101));
+ itn = pMesh->GetSubMeshContaining(v101)->GetSubMeshDS()->GetNodes();
+ N = itn->next();
+ gp_XY UV101 = myTool->GetNodeUV(TopFace,N);
+ const TopoDS_Vertex& v011 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V011));
+ itn = pMesh->GetSubMeshContaining(v011)->GetSubMeshDS()->GetNodes();
+ N = itn->next();
+ gp_XY UV011 = myTool->GetNodeUV(TopFace,N);
+ const TopoDS_Vertex& v111 = TopoDS::Vertex(myBlock.Shape(SMESH_Block::ID_V111));
+ itn = pMesh->GetSubMeshContaining(v111)->GetSubMeshDS()->GetNodes();
+ N = itn->next();
+ gp_XY UV111 = myTool->GetNodeUV(TopFace,N);
+
+ for (j=0; j<myJSize; ++j) {
// base node info
- const StdMeshers_TNode& aBN=myTNodes[j];
- aBNSSID=(SMESH_Block::TShapeID)aBN.ShapeSupportID();
- iBNID=aBN.BaseNodeID();
- const gp_XYZ& aBNXYZ=aBN.NormCoord();
+ const StdMeshers_TNode& aBN = myTNodes[j];
+ aBNSSID = (SMESH_Block::TShapeID)aBN.ShapeSupportID();
+ iBNID = aBN.BaseNodeID();
+ const gp_XYZ& aBNXYZ = aBN.NormCoord();
bool createNode = ( aBNSSID == SMESH_Block::ID_Fxy0 );
//
// set XYZ on horizontal edges and get node columns of faces:
// 2 columns for each face, between which a base node is located
vector<const SMDS_MeshNode*>* nColumns[8];
double ratio[4]; // base node position between columns [0.-1.]
- if ( createNode )
- for ( k = 0; k < 4; ++k )
+ if ( createNode ) {
+ for ( k = 0; k < 4; ++k ) {
ratio[ k ] = SetHorizEdgeXYZ (aBNXYZ, wallFaceID[ k ],
nColumns[k*2], nColumns[k*2+1]);
+ }
+ }
//
// XYZ on the bottom and top faces
const SMDS_MeshNode* n = aBN.Node();
myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( 0., 0., 0. );
//
// first create or find a top node, then the rest ones in a column
- for (i=myISize-1; i>0; --i)
- {
+ for (i=myISize-1; i>0; --i) {
+ bIsUpperLayer = (i==(myISize-1));
+ gp_XY UV_Ex01, UV_Ex11, UV_E0y1, UV_E1y1;
if ( createNode ) {
// set XYZ on vertical edges and faces
for ( k = 0; k < 4; ++k ) {
myShapeXYZ[ verticEdgeID[ k ] ].SetCoord( n->X(), n->Y(), n->Z() );
//
n = (*nColumns[k*2]) [ i ];
+ gp_XY tmp1;
+ if( i==myISize-1 ) {
+ tmp1 = myTool->GetNodeUV(TopFace,n);
+ tmp1 = ( 1. - ratio[ k ]) * tmp1;
+ }
gp_XYZ xyz( n->X(), n->Y(), n->Z() );
myShapeXYZ[ wallFaceID[ k ]] = ( 1. - ratio[ k ]) * xyz;
n = (*nColumns[k*2+1]) [ i ];
xyz.SetCoord( n->X(), n->Y(), n->Z() );
myShapeXYZ[ wallFaceID[ k ]] += ratio[ k ] * xyz;
+ if( i==myISize-1 ) {
+ gp_XY tmp2 = myTool->GetNodeUV(TopFace,n);
+ tmp1 += ratio[ k ] * tmp2;
+ if( k==0 )
+ UV_Ex01 = tmp1;
+ else if( k==1 )
+ UV_Ex11 = tmp1;
+ else if( k==2 )
+ UV_E0y1 = tmp1;
+ else
+ UV_E1y1 = tmp1;
+ }
}
}
// fill current node info
aCoords.SetCoord(aX, aY, aZ);
//
// suporting shape ID
- bIsUpperLayer=(i==(myISize-1));
ShapeSupportID(bIsUpperLayer, aBNSSID, aSSID);
if (myErrorStatus) {
MESSAGE("StdMeshers_Penta_3D::MakeNodes() ");
if ( bIsUpperLayer ) {
const SMDS_MeshNode* n = aTN.Node();
myShapeXYZ[ SMESH_Block::ID_Fxy1 ].SetCoord( n->X(), n->Y(), n->Z() );
+ // set node on top face:
+ // find UV parameter for this node
+ // UV_Ex11
+ // UV011+-----+----------+UV111
+ // | |
+ // | |
+ // UV_E0y1+ +node +UV_E1y1
+ // | |
+ // | |
+ // | |
+ // UV001+-----+----------+UV101
+ // UV_Ex01
+ gp_Pnt2d aP;
+ double u = aCoords.X(), v = aCoords.Y();
+ double u1 = ( 1. - u ), v1 = ( 1. - v );
+ aP.ChangeCoord() = UV_Ex01 * v1;
+ aP.ChangeCoord() += UV_Ex11 * v;
+ aP.ChangeCoord() += UV_E0y1 * u1;
+ aP.ChangeCoord() += UV_E1y1 * u;
+ aP.ChangeCoord() -= UV001 * u1 * v1;
+ aP.ChangeCoord() -= UV101 * u * v1;
+ aP.ChangeCoord() -= UV011 * u1 * v;
+ aP.ChangeCoord() -= UV111 * u * v;
+ meshDS->SetNodeOnFace((SMDS_MeshNode*)n, topfaceID, aP.X(), aP.Y());
}
}
if (myErrorStatus) {
*/
//DEB t
}
+
+
//=======================================================================
//function : FindNodeOnShape
//purpose :
//=======================================================================
+
void StdMeshers_Penta_3D::FindNodeOnShape(const TopoDS_Shape& aS,
const gp_XYZ& aParams,
const int z,
double aX, aY, aZ, aD, aTol2, minD;
gp_Pnt aP1, aP2;
//
- SMESH_Mesh* pMesh=GetMesh();
- aTol2=myTol3D*myTol3D;
+ SMESH_Mesh* pMesh = GetMesh();
+ aTol2 = myTol3D*myTol3D;
minD = 1.e100;
- SMDS_MeshNode* pNode=NULL;
+ SMDS_MeshNode* pNode = NULL;
//
if ( aS.ShapeType() == TopAbs_FACE ||
- aS.ShapeType() == TopAbs_EDGE )
- {
+ aS.ShapeType() == TopAbs_EDGE ) {
// find a face ID to which aTN belongs to
int faceID;
if ( aS.ShapeType() == TopAbs_FACE )
}
ASSERT( SMESH_Block::IsFaceID( faceID ));
int fIndex = SMESH_Block::ShapeIndex( faceID );
- StdMeshers_IJNodeMap & ijNodes= myWallNodesMaps[ fIndex ];
+ StdMeshers_IJNodeMap & ijNodes = myWallNodesMaps[ fIndex ];
// look for a base node in ijNodes
const SMDS_MeshNode* baseNode = pMesh->GetMeshDS()->FindNode( aTN.BaseNodeID() );
StdMeshers_IJNodeMap::const_iterator par_nVec = ijNodes.begin();
for ( ; par_nVec != ijNodes.end(); par_nVec++ )
if ( par_nVec->second[ 0 ] == baseNode ) {
- pNode=(SMDS_MeshNode*)par_nVec->second.at( z );
+ pNode = (SMDS_MeshNode*)par_nVec->second.at( z );
aTN.SetNode(pNode);
return;
}
pMesh->GetSubMeshContaining(aS)->GetSubMeshDS()->GetNodes();
while(ite->more()) {
const SMDS_MeshNode* aNode = ite->next();
+ if(myTool->IsMedium(aNode))
+ continue;
aX=aNode->X();
aY=aNode->Y();
aZ=aNode->Z();
//myErrorStatus=11; // can not find the node;
}
+
//=======================================================================
//function : SetHorizEdgeXYZ
//purpose :
return r;
}
+
//=======================================================================
//function : MakeVolumeMesh
//purpose :
//
int i, j, ij, ik, i1, i2, aSSID;
//
- SMESH_Mesh* pMesh =GetMesh();
- SMESHDS_Mesh* meshDS=pMesh->GetMeshDS();
+ SMESH_Mesh* pMesh = GetMesh();
+ SMESHDS_Mesh* meshDS = pMesh->GetMeshDS();
//
int shapeID = meshDS->ShapeToIndex( myShape );
//
// 1. Set Node In Volume
- ik=myISize-1;
+ ik = myISize-1;
for (i=1; i<ik; ++i){
for (j=0; j<myJSize; ++j){
ij=i*myJSize+j;
- const StdMeshers_TNode& aTN=myTNodes[ij];
+ const StdMeshers_TNode& aTN = myTNodes[ij];
aSSID=aTN.ShapeSupportID();
if (aSSID==SMESH_Block::ID_NONE) {
- SMDS_MeshNode* aNode=(SMDS_MeshNode*)aTN.Node();
+ SMDS_MeshNode* aNode = (SMDS_MeshNode*)aTN.Node();
meshDS->SetNodeInVolume(aNode, shapeID);
}
}
const TopoDS_Face& aFxy0=
TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy0));
SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
- SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+ SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
//
- itf=aSM0->GetElements();
+ itf = aSM0->GetElements();
while(itf->more()) {
- const SMDS_MeshElement* pE0=itf->next();
+ const SMDS_MeshElement* pE0 = itf->next();
//
int nbFaceNodes = pE0->NbNodes();
+ if(myCreateQuadratic)
+ nbFaceNodes = nbFaceNodes/2;
if ( aN.size() < nbFaceNodes * 2 )
aN.resize( nbFaceNodes * 2 );
//
k=0;
aItNodes=pE0->nodesIterator();
while (aItNodes->more()) {
- const SMDS_MeshElement* pNode=aItNodes->next();
- aID0=pNode->GetID();
- aJ[k]=GetIndexOnLayer(aID0);
+ //const SMDS_MeshElement* pNode = aItNodes->next();
+ const SMDS_MeshNode* pNode =
+ static_cast<const SMDS_MeshNode*> (aItNodes->next());
+ if(myTool->IsMedium(pNode))
+ continue;
+ aID0 = pNode->GetID();
+ aJ[k] = GetIndexOnLayer(aID0);
if (myErrorStatus) {
MESSAGE("StdMeshers_Penta_3D::MakeVolumeMesh");
return;
}
//
bool forward = true;
- for (i=0; i<ik; ++i){
+ for (i=0; i<ik; ++i) {
i1=i;
i2=i+1;
for(j=0; j<nbFaceNodes; ++j) {
- ij=i1*myJSize+aJ[j];
- const StdMeshers_TNode& aTN1=myTNodes[ij];
- const SMDS_MeshNode* aN1=aTN1.Node();
+ ij = i1*myJSize+aJ[j];
+ const StdMeshers_TNode& aTN1 = myTNodes[ij];
+ const SMDS_MeshNode* aN1 = aTN1.Node();
aN[j]=aN1;
//
ij=i2*myJSize+aJ[j];
- const StdMeshers_TNode& aTN2=myTNodes[ij];
- const SMDS_MeshNode* aN2=aTN2.Node();
- aN[j+nbFaceNodes]=aN2;
+ const StdMeshers_TNode& aTN2 = myTNodes[ij];
+ const SMDS_MeshNode* aN2 = aTN2.Node();
+ aN[j+nbFaceNodes] = aN2;
}
// check if volume orientation will be ok
if ( i == 0 ) {
SMDS_MeshVolume* aV = 0;
switch ( nbFaceNodes ) {
case 3:
- if ( forward )
- aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
- aN[3], aN[4], aN[5]);
- else
- aV = meshDS->AddVolume(aN[0], aN[2], aN[1],
- aN[3], aN[5], aN[4]);
+ if ( forward ) {
+ //aV = meshDS->AddVolume(aN[0], aN[1], aN[2],
+ // aN[3], aN[4], aN[5]);
+ aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3], aN[4], aN[5]);
+ }
+ else {
+ //aV = meshDS->AddVolume(aN[0], aN[2], aN[1],
+ // aN[3], aN[5], aN[4]);
+ aV = myTool->AddVolume(aN[0], aN[2], aN[1], aN[3], aN[5], aN[4]);
+ }
break;
case 4:
- if ( forward )
- aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+ if ( forward ) {
+ //aV = meshDS->AddVolume(aN[0], aN[1], aN[2], aN[3],
+ // aN[4], aN[5], aN[6], aN[7]);
+ aV = myTool->AddVolume(aN[0], aN[1], aN[2], aN[3],
aN[4], aN[5], aN[6], aN[7]);
- else
- aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1],
+ }
+ else {
+ //aV = meshDS->AddVolume(aN[0], aN[3], aN[2], aN[1],
+ // aN[4], aN[7], aN[6], aN[5]);
+ aV = myTool->AddVolume(aN[0], aN[3], aN[2], aN[1],
aN[4], aN[7], aN[6], aN[5]);
+ }
break;
default:
continue;
const TopoDS_Face& aFxy1=
TopoDS::Face(myBlock.Shape(SMESH_Block::ID_Fxy1));
//
- SMESH_Mesh* pMesh=GetMesh();
+ SMESH_Mesh* pMesh = GetMesh();
SMESHDS_Mesh * meshDS = pMesh->GetMeshDS();
//
SMESH_subMesh *aSubMesh0 = pMesh->GetSubMeshContaining(aFxy0);
- SMESHDS_SubMesh *aSM0=aSubMesh0->GetSubMeshDS();
+ SMESHDS_SubMesh *aSM0 = aSubMesh0->GetSubMeshDS();
//
// set nodes on aFxy1
- aLevel=myISize-1;
- itn=aSM0->GetNodes();
- aNbNodes=aSM0->NbNodes();
+ aLevel = myISize-1;
+ itn = aSM0->GetNodes();
+ aNbNodes = aSM0->NbNodes();
//printf("** aNbNodes=%d\n", aNbNodes);
- while(itn->more()) {
- const SMDS_MeshNode* aN0=itn->next();
- aID0=aN0->GetID();
- aJ=GetIndexOnLayer(aID0);
- if (myErrorStatus) {
- MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
- return;
- }
- //
- ij=aLevel*myJSize+aJ;
- const StdMeshers_TNode& aTN1=myTNodes[ij];
- SMDS_MeshNode* aN1=(SMDS_MeshNode*)aTN1.Node();
- //
- meshDS->SetNodeOnFace(aN1, aFxy1);
- }
+
//
// set elements on aFxy1
vector<const SMDS_MeshNode*> aNodes1;
//
- itf=aSM0->GetElements();
+ itf = aSM0->GetElements();
while(itf->more()) {
- const SMDS_MeshElement * pE0=itf->next();
- aElementType=pE0->GetType();
+ const SMDS_MeshElement* pE0 = itf->next();
+ aElementType = pE0->GetType();
if (!aElementType==SMDSAbs_Face) {
continue;
}
- aNbNodes=pE0->NbNodes();
+ aNbNodes = pE0->NbNodes();
+ if(myCreateQuadratic)
+ aNbNodes = aNbNodes/2;
// if (aNbNodes!=3) {
// continue;
// }
if ( aNodes1.size() < aNbNodes )
aNodes1.resize( aNbNodes );
//
- k=aNbNodes-1; // reverse a face
- aItNodes=pE0->nodesIterator();
+ k = aNbNodes-1; // reverse a face
+ aItNodes = pE0->nodesIterator();
while (aItNodes->more()) {
- const SMDS_MeshElement* pNode=aItNodes->next();
- aID0=pNode->GetID();
- aJ=GetIndexOnLayer(aID0);
+ //const SMDS_MeshElement* pNode = aItNodes->next();
+ const SMDS_MeshNode* pNode =
+ static_cast<const SMDS_MeshNode*> (aItNodes->next());
+ if(myTool->IsMedium(pNode))
+ continue;
+ aID0 = pNode->GetID();
+ aJ = GetIndexOnLayer(aID0);
if (myErrorStatus) {
MESSAGE("StdMeshers_Penta_3D::MakeMeshOnFxy1() ");
return;
}
//
- ij=aLevel*myJSize+aJ;
- const StdMeshers_TNode& aTN1=myTNodes[ij];
- const SMDS_MeshNode* aN1=aTN1.Node();
- aNodes1[k]=aN1;
+ ij = aLevel*myJSize + aJ;
+ const StdMeshers_TNode& aTN1 = myTNodes[ij];
+ const SMDS_MeshNode* aN1 = aTN1.Node();
+ aNodes1[k] = aN1;
--k;
}
SMDS_MeshFace * face = 0;
switch ( aNbNodes ) {
case 3:
- face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+ //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
+ face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2]);
break;
case 4:
- face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+ //face = meshDS->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
+ face = myTool->AddFace(aNodes1[0], aNodes1[1], aNodes1[2], aNodes1[3]);
break;
default:
continue;
meshDS->SetMeshElementOnShape(face, aFxy1);
}
}
+
//=======================================================================
//function : ClearMeshOnFxy1
//purpose :
j=(*aMapIt).second;
return j;
}
+
//=======================================================================
//function : MakeConnectingMap
//purpose :
myConnectingMap[aBNID]=j;
}
}
+
//=======================================================================
//function : CreateNode
//purpose :
// // point inside solid
// myBlock.Point(aParams, aP);
// }
- if (bIsUpperLayer)
- {
+ if (bIsUpperLayer) {
double u = aParams.X(), v = aParams.Y();
double u1 = ( 1. - u ), v1 = ( 1. - v );
aP.ChangeCoord() = myShapeXYZ[ SMESH_Block::ID_Ex01 ] * v1;
aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V011 ] * u1 * v;
aP.ChangeCoord() -= myShapeXYZ[ SMESH_Block::ID_V111 ] * u * v;
}
- else
- {
+ else {
SMESH_Block::ShellPoint( aParams, myShapeXYZ, aP.ChangeCoord() );
}
//
//
aX=aP.X(); aY=aP.Y(); aZ=aP.Z();
//
- SMESH_Mesh* pMesh=GetMesh();
- SMESHDS_Mesh* pMeshDS=pMesh->GetMeshDS();
+ SMESH_Mesh* pMesh = GetMesh();
+ SMESHDS_Mesh* pMeshDS = pMesh->GetMeshDS();
//
pNode = pMeshDS->AddNode(aX, aY, aZ);
+
aTN.SetNode(pNode);
}
+
//=======================================================================
//function : ShapeSupportID
//purpose :
SMDSAbs_ElementType aElementType;
SMESH_Mesh* pMesh=GetMesh();
//
- iCnt=0;
- iNbF=aM.Extent();
+ iCnt = 0;
+ iNbF = aM.Extent();
for (i=1; i<=iNbF; ++i) {
- const TopoDS_Shape& aF=aM(i);
+ const TopoDS_Shape& aF = aM(i);
SMESH_subMesh *aSubMesh = pMesh->GetSubMeshContaining(aF);
ASSERT(aSubMesh);
- SMESHDS_SubMesh *aSM=aSubMesh->GetSubMeshDS();
- SMDS_ElemIteratorPtr itf=aSM->GetElements();
+ SMESHDS_SubMesh *aSM = aSubMesh->GetSubMeshDS();
+ SMDS_ElemIteratorPtr itf = aSM->GetElements();
while(itf->more()) {
- const SMDS_MeshElement * pElement=itf->next();
- aElementType=pElement->GetType();
+ const SMDS_MeshElement * pElement = itf->next();
+ aElementType = pElement->GetType();
if (aElementType==SMDSAbs_Face) {
- iNbNodes=pElement->NbNodes();
- if (iNbNodes==3) {
- aFTr=aF;
+ iNbNodes = pElement->NbNodes();
+ if ( iNbNodes==3 || (myCreateQuadratic && iNbNodes==6) ) {
+ aFTr = aF;
++iCnt;
if (iCnt>1) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
TopExp::MapShapesAndAncestors(myShape, TopAbs_VERTEX, TopAbs_EDGE, aMVES);
//
// 1.1 Base vertex V000
- iNbE=aME.Extent();
+ iNbE = aME.Extent();
if (iNbE!=4){
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
myErrorStatus=7; // too few edges are in base face aFTr
// 2. Load Block
const TopoDS_Shell& aShell=TopoDS::Shell(aME(1));
myBlock.Load(aShell, aV000, aV001);
- iErr=myBlock.ErrorStatus();
+ iErr = myBlock.ErrorStatus();
if (iErr) {
MESSAGE("StdMeshers_Penta_3D::MakeBlock() ");
myErrorStatus=100; // SMESHBlock: Load operation failed
bool rev1, CumOri = false;
TopExp_Explorer exp( theFace, TopAbs_EDGE );
int nbEdges = 0;
- for ( ; exp.More(); exp.Next() )
- {
- if ( ++nbEdges > 4 )
+ for ( ; exp.More(); exp.Next() ) {
+ if ( ++nbEdges > 4 ) {
return false; // more than 4 edges in theFace
+ }
TopoDS_Edge e = TopoDS::Edge( exp.Current() );
if ( theBaseEdge.IsSame( e ))
continue;
else
e2 = e;
}
- if ( nbEdges < 4 )
- return false; // lass than 4 edges in theFace
+ if ( nbEdges < 4 ) {
+ return false; // less than 4 edges in theFace
+ }
// submeshes corresponding to shapes
SMESHDS_SubMesh* smFace = theMesh->MeshElements( theFace );
return false;
}
if ( sm1->NbNodes() * smb->NbNodes() != smFace->NbNodes() ) {
- MESSAGE( "Wrong nb face nodes: " <<
- sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
- return false;
+ // check quadratic case
+ if ( myCreateQuadratic ) {
+ int n1 = sm1->NbNodes()/2;
+ int n2 = smb->NbNodes()/2;
+ int n3 = sm1->NbNodes() - n1;
+ int n4 = smb->NbNodes() - n2;
+ int nf = sm1->NbNodes()*smb->NbNodes() - n3*n4;
+ if( nf != smFace->NbNodes() ) {
+ MESSAGE( "Wrong nb face nodes: " <<
+ sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+ return false;
+ }
+ }
+ else {
+ MESSAGE( "Wrong nb face nodes: " <<
+ sm1->NbNodes()<<" "<<smb->NbNodes()<<" "<<smFace->NbNodes());
+ return false;
+ }
}
// IJ size
int vsize = sm1->NbNodes() + 2;
int hsize = smb->NbNodes() + 2;
+ if(myCreateQuadratic) {
+ vsize = vsize - sm1->NbNodes()/2 -1;
+ hsize = hsize - smb->NbNodes()/2 -1;
+ }
// load nodes from theBaseEdge
double range = l - f;
SMDS_NodeIteratorPtr nIt = smb->GetNodes();
const SMDS_MeshNode* node;
- while ( nIt->more() )
- {
+ while ( nIt->more() ) {
node = nIt->next();
+ if(myTool->IsMedium(node))
+ continue;
const SMDS_EdgePosition* pos =
dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
- if ( !pos ) return false;
+ if ( !pos ) {
+ return false;
+ }
double u = ( pos->GetUParameter() - f ) / range;
vector<const SMDS_MeshNode*> & nVec = theIJNodes[ u ];
nVec.resize( vsize, nullNode );
map< double, const SMDS_MeshNode*> sortedNodes; // sort by param on edge
nIt = sm1->GetNodes();
- while ( nIt->more() )
- {
+ while ( nIt->more() ) {
node = nIt->next();
+ if(myTool->IsMedium(node))
+ continue;
const SMDS_EdgePosition* pos =
dynamic_cast<const SMDS_EdgePosition*>( node->GetPosition().get() );
- if ( !pos ) return false;
+ if ( !pos ) {
+ return false;
+ }
sortedNodes.insert( make_pair( pos->GetUParameter(), node ));
}
loadedNodes.insert( nVecf[ vsize - 1 ] = smVft->GetNodes()->next() );
map< double, const SMDS_MeshNode*>::iterator u_n = sortedNodes.begin();
int row = rev1 ? vsize - 1 : 0;
- for ( ; u_n != sortedNodes.end(); u_n++ )
- {
+ for ( ; u_n != sortedNodes.end(); u_n++ ) {
if ( rev1 ) row--;
else row++;
loadedNodes.insert( nVecf[ row ] = u_n->second );
StdMeshers_IJNodeMap::iterator par_nVec_2 = par_nVec_1;
// loop on columns
int col = 0;
- for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ )
- {
+ for ( par_nVec_2++; par_nVec_2 != theIJNodes.end(); par_nVec_1++, par_nVec_2++ ) {
col++;
row = 0;
const SMDS_MeshNode* n1 = par_nVec_1->second[ row ];
do {
// look for a face by 2 nodes
face = SMESH_MeshEditor::FindFaceInSet( n1, n2, allFaces, foundFaces );
- if ( face )
- {
+ if ( face ) {
int nbFaceNodes = face->NbNodes();
- if ( nbFaceNodes > 4 ) {
+ if ( (!myCreateQuadratic && nbFaceNodes>4) ||
+ (myCreateQuadratic && nbFaceNodes>8) ) {
MESSAGE(" Too many nodes in a face: " << nbFaceNodes );
return false;
}
eIt = face->nodesIterator() ;
while ( !found && eIt->more() ) {
node = static_cast<const SMDS_MeshNode*>( eIt->next() );
+ if(myTool->IsMedium(node))
+ continue;
found = loadedNodes.insert( node ).second;
if ( !found && node != n1 && node != n2 )
n3 = node;
par_nVec_2->second[ row ] = node;
foundFaces.insert( face );
n2 = node;
- if ( nbFaceNodes == 4 )
+ if ( nbFaceNodes==4 || (myCreateQuadratic && nbFaceNodes==8) ) {
n1 = par_nVec_1->second[ row ];
+ }
}
- else if (nbFaceNodes == 3 &&
- n3 == par_nVec_1->second[ row ] )
+ else if ( (nbFaceNodes==3 || (myCreateQuadratic && nbFaceNodes==6) ) &&
+ n3 == par_nVec_1->second[ row ] ) {
n1 = n3;
+ }
else {
MESSAGE( "Not quad mesh, column "<< col );
return false;
}
}
- } while ( face && n1 && n2 );
+ }
+ while ( face && n1 && n2 );
if ( row < vsize - 1 ) {
MESSAGE( "Too few nodes in column "<< col <<": "<< row+1);
{
return myErrorStatus;
}
+
//=======================================================================
//function : Load
//purpose :
//=======================================================================
void StdMeshers_SMESHBlock::Load(const TopoDS_Shell& theShell)
{
-
TopoDS_Vertex aV000, aV001;
//
Load(theShell, aV000, aV001);
}
+
//=======================================================================
//function : Load
//purpose :
bool bOk;
//
myShapeIDMap.Clear();
- bOk=myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
+ bOk = myTBlock.LoadBlockShapes(myShell, theV000, theV001, myShapeIDMap);
if (!bOk) {
myErrorStatus=2;
return;
}
}
+
//=======================================================================
//function : ComputeParameters
//purpose :
{
ComputeParameters(thePnt, myShell, theXYZ);
}
+
//=======================================================================
//function : ComputeParameters
//purpose :
//=======================================================================
void StdMeshers_SMESHBlock::ComputeParameters(const gp_Pnt& thePnt,
const TopoDS_Shape& theShape,
- gp_XYZ& theXYZ)
+ gp_XYZ& theXYZ)
{
myErrorStatus=0;
//
int aID;
bool bOk;
//
- aID=ShapeID(theShape);
+ aID = ShapeID(theShape);
if (myErrorStatus) {
return;
}
- bOk=myTBlock.ComputeParameters(thePnt, theXYZ, aID);
+ bOk = myTBlock.ComputeParameters(thePnt, theXYZ, aID);
if (!bOk) {
myErrorStatus=4; // problems with computation Parameters
return;
int aID;
bool bOk=false;
//
- aID=ShapeID(theShape);
+ aID = ShapeID(theShape);
if (myErrorStatus) {
return;
}
if ( SMESH_Block::IsEdgeID( aID ))
- bOk=myTBlock.EdgeParameters( aID, theU, theXYZ );
+ bOk = myTBlock.EdgeParameters( aID, theU, theXYZ );
if (!bOk) {
myErrorStatus=4; // problems with computation Parameters
return;
//
Point(theParams, aS, aP3D);
}
+
//=======================================================================
//function : Point
//purpose :
const TopoDS_Shape& theShape,
gp_Pnt& aP3D)
{
- myErrorStatus=0;
+ myErrorStatus = 0;
//
int aID;
- bool bOk=false;
+ bool bOk = false;
gp_XYZ aXYZ(99.,99.,99.);
aP3D.SetXYZ(aXYZ);
//
if (theShape.IsNull()) {
- bOk=myTBlock.ShellPoint(theParams, aXYZ);
+ bOk = myTBlock.ShellPoint(theParams, aXYZ);
}
//
else {
}
//
if (SMESH_Block::IsVertexID(aID)) {
- bOk=myTBlock.VertexPoint(aID, aXYZ);
+ bOk = myTBlock.VertexPoint(aID, aXYZ);
}
else if (SMESH_Block::IsEdgeID(aID)) {
- bOk=myTBlock.EdgePoint(aID, theParams, aXYZ);
+ bOk = myTBlock.EdgePoint(aID, theParams, aXYZ);
}
//
else if (SMESH_Block::IsFaceID(aID)) {
- bOk=myTBlock.FacePoint(aID, theParams, aXYZ);
+ bOk = myTBlock.FacePoint(aID, theParams, aXYZ);
}
}
if (!bOk) {
}
aP3D.SetXYZ(aXYZ);
}
+
//=======================================================================
//function : ShapeID
//purpose :
myErrorStatus=2; // unknown shape;
return aID;
}
+
//=======================================================================
//function : Shape
//purpose :
const TopoDS_Shape& aS=myShapeIDMap.FindKey(theID);
return aS;
}
+
+
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Shell.hxx>
#include <TopTools_IndexedMapOfOrientedShape.hxx>
+#include <TColStd_MapOfInteger.hxx>
#include "SMESH_Block.hxx"
+#include "StdMeshers_Helper.hxx"
+
typedef std::map< double, std::vector<const SMDS_MeshNode*> > StdMeshers_IJNodeMap;
class StdMeshers_SMESHBlock {
return myTol3D;
}
- static bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
- const TopoDS_Face& theFace,
- const TopoDS_Edge& theBaseEdge,
- SMESHDS_Mesh* theMesh);
+ bool LoadIJNodes(StdMeshers_IJNodeMap & theIJNodes,
+ const TopoDS_Face& theFace,
+ const TopoDS_Edge& theBaseEdge,
+ SMESHDS_Mesh* theMesh);
// Load nodes bound to theFace into column (vectors) and rows
// of theIJNodes.
// The value of theIJNodes map is a vector of ordered nodes so
//
vector<StdMeshers_IJNodeMap> myWallNodesMaps; // nodes on a face
vector<gp_XYZ> myShapeXYZ; // point on each sub-shape
+
+ bool myCreateQuadratic;
+ StdMeshers_Helper* myTool; // toll for working with quadratic elements
};
#endif
#include <Geom2d_Curve.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GCPnts_UniformAbscissa.hxx>
+#include <TopExp.hxx>
#include <Precision.hxx>
#include <gp_Pnt2d.hxx>
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
aMesh.GetSubMesh(aShape);
+ bool QuadMode = true;
+
+ myTool = new StdMeshers_Helper(aMesh);
+ myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape,QuadMode);
+
//FaceQuadStruct *quad = CheckAnd2Dcompute(aMesh, aShape);
FaceQuadStruct* quad = CheckNbEdges(aMesh, aShape);
quad->uv_grid[ij].node = node;
}
}
-
+
// mesh faces
// [2]
// 0 > > > > > > > > nbhoriz
// i
// [0]
-
+
i = 0;
int ilow = 0;
int iup = nbhoriz - 1;
if (quad->isEdgeOut[3]) { ilow++; } else { if (quad->isEdgeOut[1]) iup--; }
-
+
int jlow = 0;
int jup = nbvertic - 1;
if (quad->isEdgeOut[0]) { jlow++; } else { if (quad->isEdgeOut[2]) jup--; }
-
+
// regular quadrangles
for (i = ilow; i < iup; i++) {
for (j = jlow; j < jup; j++) {
b = quad->uv_grid[j * nbhoriz + i + 1].node;
c = quad->uv_grid[(j + 1) * nbhoriz + i + 1].node;
d = quad->uv_grid[(j + 1) * nbhoriz + i].node;
- SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
+ //SMDS_MeshFace * face = meshDS->AddFace(a, b, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
-
+
UVPtStruct *uv_e0 = quad->uv_edges[0];
UVPtStruct *uv_e1 = quad->uv_edges[1];
UVPtStruct *uv_e2 = quad->uv_edges[2];
double eps = Precision::Confusion();
// Boundary quadrangles
-
+
if (quad->isEdgeOut[0]) {
// Down edge is out
//
// . . . . . . . . . __ down edge nodes
//
// >->->->->->->->->->->->-> -- direction of processing
-
+
int g = 0; // number of last processed node in the regular grid
-
+
// number of last node of the down edge to be processed
int stop = nbdown - 1;
// if right edge is out, we will stop at a node, previous to the last one
if (quad->isEdgeOut[1]) stop--;
-
+
// for each node of the down edge find nearest node
// in the first row of the regular grid and link them
for (i = 0; i < stop; i++) {
a = uv_e0[i].node;
b = uv_e0[i + 1].node;
gp_Pnt pb (b->X(), b->Y(), b->Z());
-
+
// find node c in the regular grid, which will be linked with node b
int near = g;
if (i == stop - 1) {
// right bound reached, link with the rightmost node
near = iup;
c = quad->uv_grid[nbhoriz + iup].node;
- } else {
+ }
+ else {
// find in the grid node c, nearest to the b
double mind = RealLast();
for (int k = g; k <= iup; k++) {
-
+
const SMDS_MeshNode *nk;
if (k < ilow) // this can be, if left edge is out
nk = uv_e3[1].node; // get node from the left edge
}
if (near == g) { // make triangle
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c);
meshDS->SetMeshElementOnShape(face, geomFaceID);
- } else { // make quadrangle
+ }
+ else { // make quadrangle
if (near - 1 < ilow)
d = uv_e3[1].node;
else
d = quad->uv_grid[nbhoriz + near - 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
// if node d is not at position g - make additional triangles
d = uv_e3[1].node;
else
d = quad->uv_grid[nbhoriz + k - 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
}
if (near == g) { // make triangle
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c);
meshDS->SetMeshElementOnShape(face, geomFaceID);
- } else { // make quadrangle
+ }
+ else { // make quadrangle
if (near + 1 > iup)
d = uv_e1[nbright - 2].node;
else
d = quad->uv_grid[nbhoriz*(nbvertic - 2) + near + 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
if (near + 1 < g) { // if d not is at g - make additional triangles
d = uv_e1[nbright - 2].node;
else
d = quad->uv_grid[nbhoriz*(nbvertic - 2) + k + 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
}
if (near == g) { // make triangle
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c);
meshDS->SetMeshElementOnShape(face, geomFaceID);
- } else { // make quadrangle
+ }
+ else { // make quadrangle
if (near - 1 < jlow)
d = uv_e0[nbdown - 2].node;
else
d = quad->uv_grid[nbhoriz*near - 2].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
if (near - 1 > g) { // if d not is at g - make additional triangles
d = uv_e0[nbdown - 2].node;
else
d = quad->uv_grid[nbhoriz*k - 2].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
}
if (near == g) { // make triangle
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c);
meshDS->SetMeshElementOnShape(face, geomFaceID);
- } else { // make quadrangle
+ }
+ else { // make quadrangle
if (near + 1 > jup)
d = uv_e2[1].node;
else
d = quad->uv_grid[nbhoriz*(near + 1) + 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, b, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, b, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
if (near + 1 < g) { // if d not is at g - make additional triangles
d = uv_e2[1].node;
else
d = quad->uv_grid[nbhoriz*(k + 1) + 1].node;
- SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ //SMDS_MeshFace* face = meshDS->AddFace(a, c, d);
+ SMDS_MeshFace* face = myTool->AddFace(a, c, d);
meshDS->SetMeshElementOnShape(face, geomFaceID);
}
}
int nb = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
if (nbEdges < 4) {
quad->edge[nbEdges] = E;
- quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+ if(!myCreateQuadratic) {
+ quad->nbPts[nbEdges] = nb + 2; // internal points + 2 extrema
+ }
+ else {
+ int tmp = nb/2;
+ quad->nbPts[nbEdges] = tmp + 2; // internal not medium points + 2 extrema
+ }
}
nbEdges++;
}
//=============================================================================
/*!
- *
+ * CheckAnd2Dcompute
*/
//=============================================================================
FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape) throw(SALOME_Exception)
+{
+ bool QuadMode = true;
+ myTool = new StdMeshers_Helper(aMesh);
+ myCreateQuadratic = myTool->IsQuadraticSubMesh(aShape,QuadMode);
+ return CheckAnd2Dcompute(aMesh,aShape,myCreateQuadratic);
+}
+
+
+//=============================================================================
+/*!
+ * CheckAnd2Dcompute
+ */
+//=============================================================================
+
+FaceQuadStruct *StdMeshers_Quadrangle_2D::CheckAnd2Dcompute
+ (SMESH_Mesh & aMesh,
+ const TopoDS_Shape & aShape,
+ const bool CreateQuadratic) throw(SALOME_Exception)
{
Unexpect aCatch(SalomeException);
+ myCreateQuadratic = CreateQuadratic;
+
FaceQuadStruct *quad = CheckNbEdges(aMesh, aShape);
if(!quad) return 0;
for(j=1; j<nl; j++) {
if(WisF) {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
+ myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i+1,j),
NodesL.Value(i+1,j+1), NodesL.Value(i,j+1));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
+ myTool->AddFace(NodesL.Value(i,j), NodesL.Value(i,j+1),
NodesL.Value(i+1,j+1), NodesL.Value(i+1,j));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
for(j=1; j<nr; j++) {
if(WisF) {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
+ myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i+1,j),
NodesR.Value(i+1,j+1), NodesR.Value(i,j+1));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
+ myTool->AddFace(NodesR.Value(i,j), NodesR.Value(i,j+1),
NodesR.Value(i+1,j+1), NodesR.Value(i+1,j));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
for(j=1; j<nbv; j++) {
if(WisF) {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
+ myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i+1,j),
NodesC.Value(i+1,j+1), NodesC.Value(i,j+1));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
else {
SMDS_MeshFace* F =
- meshDS->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
+ myTool->AddFace(NodesC.Value(i,j), NodesC.Value(i,j+1),
NodesC.Value(i+1,j+1), NodesC.Value(i+1,j));
meshDS->SetMeshElementOnShape(F, geomFaceID);
}
// --- edge internal IDNodes (relies on good order storage, not checked)
+// if(myCreateQuadratic) {
+ // fill myNLinkNodeMap
+// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
+// while(iter->more()) {
+// const SMDS_MeshElement* elem = iter->next();
+// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+// const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
+// myNLinkNodeMap[link] = n3;
+// }
+// }
+
map<double, const SMDS_MeshNode *> params;
SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+ int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- while(ite->more()) {
- const SMDS_MeshNode* node = ite->next();
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
+ if(!myCreateQuadratic) {
+ while(ite->more()) {
+ const SMDS_MeshNode* node = ite->next();
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
+ }
+ else {
+ vector<const SMDS_MeshNode*> nodes(nbPoints+2);
+ nodes[0] = idFirst;
+ nodes[nbPoints+1] = idLast;
+ nbPoints = nbPoints/2;
+ int nn = 1;
+ while(ite->more()) {
+ const SMDS_MeshNode* node = ite->next();
+ nodes[nn++] = node;
+ // check if node is medium
+ bool IsMedium = false;
+ SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+ while (itn->more()) {
+ const SMDS_MeshElement* elem = itn->next();
+ if ( elem->GetType() != SMDSAbs_Edge )
+ continue;
+ if(elem->IsMediumNode(node)) {
+ IsMedium = true;
+ break;
+ }
+ }
+ if(IsMedium)
+ continue;
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
}
- int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
if (nbPoints != params.size()) {
MESSAGE( "BAD NODE ON EDGE POSITIONS" );
return 0;
// --- edge internal IDNodes (relies on good order storage, not checked)
+// if(myCreateQuadratic) {
+ // fill myNLinkNodeMap
+// SMDS_ElemIteratorPtr iter = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetElements();
+// while(iter->more()) {
+// const SMDS_MeshElement* elem = iter->next();
+// SMDS_ElemIteratorPtr nodeIt = elem->nodesIterator();
+// const SMDS_MeshNode* n1 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n2 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// const SMDS_MeshNode* n3 = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+// NLink link(( n1 < n2 ? n1 : n2 ), ( n1 < n2 ? n2 : n1 ));
+// myNLinkNodeMap.insert(NLinkNodeMap::value_type(link,n3));
+// myNLinkNodeMap[link] = n3;
+// }
+// }
+
map<double, const SMDS_MeshNode *> params;
SMDS_NodeIteratorPtr ite = aMesh.GetSubMesh(E)->GetSubMeshDS()->GetNodes();
+ int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- while(ite->more())
- {
- const SMDS_MeshNode* node = ite->next();
- const SMDS_EdgePosition* epos =
- static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
- double param = epos->GetUParameter();
- params[param] = node;
+ if(!myCreateQuadratic) {
+ while(ite->more()) {
+ const SMDS_MeshNode* node = ite->next();
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
+ }
+ else {
+ nbPoints = nbPoints/2;
+ while(ite->more()) {
+ const SMDS_MeshNode* node = ite->next();
+ // check if node is medium
+ bool IsMedium = false;
+ SMDS_ElemIteratorPtr itn = node->GetInverseElementIterator();
+ while (itn->more()) {
+ const SMDS_MeshElement* elem = itn->next();
+ if ( elem->GetType() != SMDSAbs_Edge )
+ continue;
+ if(elem->IsMediumNode(node)) {
+ IsMedium = true;
+ break;
+ }
+ }
+ if(IsMedium)
+ continue;
+ const SMDS_EdgePosition* epos =
+ static_cast<const SMDS_EdgePosition*>(node->GetPosition().get());
+ double param = epos->GetUParameter();
+ params[param] = node;
+ }
}
- int nbPoints = aMesh.GetSubMesh(E)->GetSubMeshDS()->NbNodes();
- if (nbPoints != params.size())
- {
+ if (nbPoints != params.size()) {
MESSAGE( "BAD NODE ON EDGE POSITIONS" );
return 0;
}
#include "SMESH_Mesh.hxx"
#include "Utils_SALOME_Exception.hxx"
-class SMDS_MeshNode;
+#include "gp_XY.hxx"
+
+#include "StdMeshers_Helper.hxx"
+
+//class SMDS_MeshNode;
typedef struct uvPtStruct
{
const TopoDS_Shape& aShape)
throw (SALOME_Exception);
+ FaceQuadStruct* CheckAnd2Dcompute(SMESH_Mesh& aMesh,
+ const TopoDS_Shape& aShape,
+ const bool CreateQuadratic)
+ throw (SALOME_Exception);
+
static void QuadDelete(FaceQuadStruct* quad);
+ /**
+ * Returns NLinkNodeMap from myTool
+ */
+ const NLinkNodeMap& GetNLinkNodeMap() { return myTool->GetNLinkNodeMap(); }
+
ostream & SaveTo(ostream & save);
istream & LoadFrom(istream & load);
friend ostream & operator << (ostream & save, StdMeshers_Quadrangle_2D & hyp);
// construction of quadrangles if the number of nodes on opposite edges
// is not the same in the case where the global number of nodes on edges is even
bool myQuadranglePreference;
+
+ StdMeshers_Helper* myTool; // toll for working with quadratic elements
};
#endif
:SMESH_Hypothesis(hypId, studyId, gen)
{
_name = "QuadraticMesh";
- _param_algo_dim = 1; // is used by StdMeshers_Regular_1D
+ // only one hypo of the same dim can be assigned to the shape so
+ // we use -3 in order to distingush from any usual 1D hypothsis and
+ // from "NotConformAllowed" (-1) and "Propagation" (-2)
+ _param_algo_dim = -3;
}
//=============================================================================
// quardatic mesh required?
SMESH_HypoFilter filter( SMESH_HypoFilter::HasName( "QuadraticMesh" ));
- bool isQuadraticMesh = aMesh->GetHypothesis( aShape, filter, true );
+ bool QuadMode = aMesh.GetHypothesis( aShape, filter, true );
const TopoDS_Edge & EE = TopoDS::Edge(aShape);
TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
ASSERT(!VLast.IsNull());
lid=aMesh.GetSubMesh(VLast)->GetSubMeshDS()->GetNodes();
- if (!lid->more())
- {
+ if (!lid->more()) {
MESSAGE (" NO NODE BUILT ON VERTEX ");
return false;
}
const SMDS_MeshNode * idLast = lid->next();
- if (!Curve.IsNull())
- {
+ if (!Curve.IsNull()) {
list< double > params;
bool reversed = false;
if ( !_mainEdge.IsNull() )
// only internal nodes receive an edge position with param on curve
const SMDS_MeshNode * idPrev = idFirst;
+ double parPrev = f;
+ double parLast = l;
+ if(reversed) {
+ parPrev = l;
+ parLast = f;
+ }
- for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++)
- {
+ for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
double param = *itU;
gp_Pnt P = Curve->Value(param);
SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
meshDS->SetNodeOnEdge(node, shapeID, param);
- SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
- meshDS->SetMeshElementOnShape(edge, shapeID);
+ if(QuadMode) {
+ // create medium node
+ double prm = ( parPrev + param )/2;
+ gp_Pnt PM = Curve->Value(prm);
+ SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+ meshDS->SetNodeOnEdge(NM, shapeID, prm);
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
+ else {
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
+
idPrev = node;
+ parPrev = param;
+ }
+ if(QuadMode) {
+ double prm = ( parPrev + parLast )/2;
+ gp_Pnt PM = Curve->Value(prm);
+ SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+ meshDS->SetNodeOnEdge(NM, shapeID, prm);
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
+ else {
+ SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
}
- SMDS_MeshEdge* edge = meshDS->AddEdge(idPrev, idLast);
- meshDS->SetMeshElementOnShape(edge, shapeID);
}
- else
- {
+ else {
// Edge is a degenerated Edge : We put n = 5 points on the edge.
int NbPoints = 5;
BRep_Tool::Range(E, f, l);
gp_Pnt P = BRep_Tool::Pnt(V1);
const SMDS_MeshNode * idPrev = idFirst;
- for (int i = 2; i < NbPoints; i++)
- {
+ for (int i = 2; i < NbPoints; i++) {
double param = f + (i - 1) * du;
SMDS_MeshNode * node = meshDS->AddNode(P.X(), P.Y(), P.Z());
+ if(QuadMode) {
+ // create medium node
+ double prm = param - du/2.;
+ gp_Pnt PM = Curve->Value(prm);
+ SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+ meshDS->SetNodeOnEdge(NM, shapeID, prm);
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node, NM);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
+ else {
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
meshDS->SetNodeOnEdge(node, shapeID, param);
-
- SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, node);
- meshDS->SetMeshElementOnShape(edge, shapeID);
idPrev = node;
}
- SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
- meshDS->SetMeshElementOnShape(edge, shapeID);
+ if(QuadMode) {
+ // create medium node
+ double prm = l - du/2.;
+ gp_Pnt PM = Curve->Value(prm);
+ SMDS_MeshNode * NM = meshDS->AddNode(PM.X(), PM.Y(), PM.Z());
+ meshDS->SetNodeOnEdge(NM, shapeID, prm);
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast, NM);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
+ else {
+ SMDS_MeshEdge * edge = meshDS->AddEdge(idPrev, idLast);
+ meshDS->SetMeshElementOnShape(edge, shapeID);
+ }
}
return true;
}