-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
#include "StdMeshers_QuadToTriaAdaptor.hxx"
#include "SMDS_SetIterator.hxx"
-
+#include "SMESHDS_GroupBase.hxx"
#include "SMESH_Algo.hxx"
+#include "SMESH_Group.hxx"
+#include "SMESH_MeshAlgos.hxx"
#include "SMESH_MesherHelper.hxx"
#include <IntAna_IntConicQuad.hxx>
#include <gp_Lin.hxx>
#include <gp_Pln.hxx>
+#include "utilities.h"
+
+#include <string>
#include <numeric>
#include <limits>
bool tooClose = ( angle < 15. * M_PI / 180. );
// Check if pyramids collide
- if ( !tooClose && baI * baJ > 0 )
+ if ( !tooClose && ( baI * baJ > 0 ) && ( nI * nJ > 0 ))
{
// find out if nI points outside of PrmI or inside
int dInd = baseNodesIndI[1] - baseNodesIndI[0];
TIDSortedElemSet emptySet, avoidSet;
int i1, i2;
while ( const SMDS_MeshElement* f =
- SMESH_MeshEditor::FindFaceInSet( baseNodes[0], baseNodes[1],
- emptySet, avoidSet, &i1, &i2 ))
+ SMESH_MeshAlgos::FindFaceInSet( baseNodes[0], baseNodes[1],
+ emptySet, avoidSet, &i1, &i2 ))
{
avoidSet.insert( f );
}
}
- // Within pyramids, replace nodes to remove by nodes to keep
+ // Within pyramids, replace nodes to remove by nodes to keep
for ( unsigned i = 0; i < pyrams.size(); ++i )
{
// find and remove coincided faces of merged pyramids
vector< const SMDS_MeshElement* > inverseElems
- // copy inverse elements to avoid iteration on changing container
+ // copy inverse elements to avoid iteration on changing container
( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd);
for ( unsigned i = 0; i < inverseElems.size(); ++i )
{
const SMDS_MeshElement* NotCheckedFace)
{
if ( !myElemSearcher )
- myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+ myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *aMesh.GetMeshDS() );
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
//SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
gp_Ax1 line( P, gp_Vec(P,PC));
vector< const SMDS_MeshElement* > suspectElems;
searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
-
+
for ( int i = 0; i < suspectElems.size(); ++i )
{
const SMDS_MeshElement* face = suspectElems[i];
if ( face == NotCheckedFace ) continue;
Handle(TColgp_HSequenceOfPnt) aContour = new TColgp_HSequenceOfPnt;
- for ( int i = 0; i < face->NbCornerNodes(); ++i )
+ for ( int i = 0; i < face->NbCornerNodes(); ++i )
aContour->Append( SMESH_TNodeXYZ( face->GetNode(i) ));
if( HasIntersection(P, PC, Pres, aContour) ) {
res = true;
//=======================================================================
//function : Compute
-//purpose :
+//purpose :
//=======================================================================
bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh,
if ( myElemSearcher ) delete myElemSearcher;
if ( aProxyMesh )
- myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
+ myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS, aProxyMesh->GetFaces(aShape));
else
- myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+ myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
const SMESHDS_SubMesh * aSubMeshDSFace;
Handle(TColgp_HArray1OfPnt) PN = new TColgp_HArray1OfPnt(1,5);
{
bool isRev = false;
if ( helper.NbAncestors( aShapeFace, aMesh, aShape.ShapeType() ) > 1 )
- isRev = SMESH_Algo::IsReversedSubMesh( TopoDS::Face(aShapeFace), meshDS );
+ isRev = helper.IsReversedSubMesh( TopoDS::Face(aShapeFace) );
SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements();
while ( iteratorElem->more() ) // loop on elements on a geometrical face
delete myElemSearcher;
myElemSearcher =
- SMESH_MeshEditor(&aMesh).GetElementSearcher( aProxyMesh->GetFaces(aShape));
+ SMESH_MeshAlgos::GetElementSearcher( *meshDS, aProxyMesh->GetFaces(aShape));
}
}
}
if ( aMesh.NbQuadrangles() < 1 )
return false;
+ // find if there is a group of faces identified as skin faces, with normal going outside the volume
+ std::string groupName = "skinFaces";
+ SMESHDS_GroupBase* groupDS = 0;
+ SMESH_Mesh::GroupIteratorPtr groupIt = aMesh.GetGroups();
+ while ( groupIt->more() )
+ {
+ groupDS = 0;
+ SMESH_Group * group = groupIt->next();
+ if ( !group ) continue;
+ groupDS = group->GetGroupDS();
+ if ( !groupDS || groupDS->IsEmpty() )
+ {
+ groupDS = 0;
+ continue;
+ }
+ if (groupDS->GetType() != SMDSAbs_Face)
+ {
+ groupDS = 0;
+ continue;
+ }
+ std::string grpName = group->GetName();
+ if (grpName == groupName)
+ {
+ MESSAGE("group skinFaces provided");
+ break;
+ }
+ else
+ groupDS = 0;
+ }
+
vector<const SMDS_MeshElement*> myPyramids;
SMESH_MesherHelper helper(aMesh);
helper.IsQuadraticSubMesh(aMesh.GetShapeToMesh());
helper.SetElementsOnShape( true );
- if ( !myElemSearcher )
- myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
- SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
-
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
SMESH_ProxyMesh::SubMesh* prxSubMesh = getProxySubMesh();
+ if ( !myElemSearcher )
+ myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
+ SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
+
SMDS_FaceIteratorPtr fIt = meshDS->facesIterator(/*idInceasingOrder=*/true);
- while( fIt->more())
+ while( fIt->more())
{
const SMDS_MeshElement* face = fIt->next();
if ( !face ) continue;
continue;
}
- // Case of non-degenerated quadrangle
+ // Case of non-degenerated quadrangle
// Find pyramid peak
}
}
+ // if the face belong to the group of skinFaces, do not build a pyramid outside
+ if (groupDS && groupDS->Contains(face))
+ {
+ intersected[0] = false;
+ }
+ else if ( intersected[0] && intersected[1] ) // check if one of pyramids is in a hole
+ {
+ gp_Pnt P ( PC.XYZ() + tmpDir.XYZ() * 0.5 * PC.Distance( intPnt[0] ));
+ if ( searcher->GetPointState( P ) == TopAbs_OUT )
+ intersected[0] = false;
+ else
+ {
+ P = ( PC.XYZ() - tmpDir.XYZ() * 0.5 * PC.Distance( intPnt[1] ));
+ if ( searcher->GetPointState( P ) == TopAbs_OUT )
+ intersected[1] = false;
+ }
+ }
+
// Create one or two pyramids
for ( int isRev = 0; isRev < 2; ++isRev )
int i, j, k, myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
if ( myElemSearcher ) delete myElemSearcher;
- myElemSearcher = SMESH_MeshEditor(&aMesh).GetElementSearcher();
+ myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS );
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
set<const SMDS_MeshNode*> nodesToMove;
while ( vIt->more() )
{
const SMDS_MeshElement* PrmJ = vIt->next();
- if ( SMESH_Algo::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
+ if ( SMESH_MeshAlgos::GetCommonNodes( PrmI, PrmJ ).size() > 1 )
checkedPyrams.insert( PrmJ );
}
}
for(k=0; k<4 && !hasInt; k++) {
gp_Vec Vtmp(PsI[k],PsI[4]);
gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex
- hasInt =
+ hasInt =
( HasIntersection3( Pshift, PsI[4], Pint, PsJ[0], PsJ[1], PsJ[4]) ||
HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[4]) ||
HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[4]) ||
for(k=0; k<4 && !hasInt; k++) {
gp_Vec Vtmp(PsJ[k],PsJ[4]);
gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01;
- hasInt =
+ hasInt =
( HasIntersection3( Pshift, PsJ[4], Pint, PsI[0], PsI[1], PsI[4]) ||
HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[4]) ||
HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[4]) ||
PCi += PsI[k].XYZ();
PCj += PsJ[k].XYZ();
}
- PCi /= 4; PCj /= 4;
+ PCi /= 4; PCj /= 4;
gp_Vec VN1(PCi,PsI[4]);
gp_Vec VN2(PCj,PsJ[4]);
gp_Vec VI1(PCi,Pint);
nodesToMove.insert( aNode1 );
nodesToMove.insert( aNode2 );
}
- // fix intersections that could appear after apex movement
+ // fix intersections that can appear after apex movement
MergeAdjacent( PrmI, nodesToMove );
MergeAdjacent( PrmJ, nodesToMove );