Merge branch 'V7_dev' into V8_0_0_BR

This commit is contained in:
vsr 2016-01-25 16:32:07 +03:00
commit 63c75f2e20
15 changed files with 507 additions and 374 deletions

View File

@ -68,30 +68,30 @@ The following dialog will appear:
the \ref filtering_elements "Selection filters" page.</li> the \ref filtering_elements "Selection filters" page.</li>
</ul> </ul>
</li> </li>
<li>If the <b>Extrusion to Distance</b> radio button is selected
- specify the translation vector by which the elements will be extruded.
</li>
<p><br></p>
\image html extrusionalongaline2.png <li>If the <b>Extrusion to Distance</b> radio button is selected
<ul>
<li> specify the translation vector by which the elements will
be extruded.</li>
</ul>
</li>
<li>If the <b>Extrusion Along Vector</b> radio button is selected <li>If the <b>Extrusion Along Vector</b> radio button is selected
\image html extrusionalongaline2.png
<ul> <ul>
<li>specify the coordinates of the \b Vector along which the elements <li>specify the components of the \b Vector along which the elements
will be extruded, either directly or by selecting the mesh face (the will be extruded, either directly or by selecting the mesh face (the
normal to the face will define the vector),</li> normal to the face will define the vector),</li>
<li>specify the \b Distance of extrusion along the vector (it can <li>specify the \b Distance of extrusion along the vector (it can
be negative).</li> be negative).</li>
</ul> </ul>
</li> </li>
<p><br></p>
\image html extrusionalongaline3.png
<li>If the <b>Extrusion By Normal</b> radio button is selected, <li>If the <b>Extrusion By Normal</b> radio button is selected,
every node of the selected faces is extruded along the \a average every node of the selected faces is extruded along the \a average
of the \a normal vectors to the faces sharing the node. (Nodes and of the \a normal vectors to the faces sharing the node. (Nodes and
edges cannot be extruded in this mode.) edges cannot be extruded in this mode.)
\image html extrusionalongaline3.png
<ul> <ul>
<li>Specify the \b Distance of extrusion (it can be negative),</li> <li>Specify the \b Distance of extrusion (it can be negative),</li>
<li>Use <b>Along average normal</b> check-box to specify along <li>Use <b>Along average normal</b> check-box to specify along

View File

@ -134,9 +134,11 @@ The following dialog will appear:
<li>If the path of extrusion is curvilinear, at each iteration the <li>If the path of extrusion is curvilinear, at each iteration the
extruded elements are rotated to keep its initial angularity to the extruded elements are rotated to keep its initial angularity to the
curve. By default, the <b>Base Point</b> around which the elements curve. By default, the <b>Base Point</b> around which the elements
are rotated is the mass center of the elements, however, you can are rotated is the mass center of the elements (note that it can
specify any point as the <b>Base Point</b> and the elements will be differ from the gravity center computed by \a Geometry module for the
rotated with respect to this point.<br> underlying shape), however, you can specify any point as the <b>Base
Point</b> and the elements will be rotated with respect to this
point.<br>
Note that only the displacement of the <b>Base Point</b> exactly Note that only the displacement of the <b>Base Point</b> exactly
equals to the path, and all other extruded elements simply keep equals to the path, and all other extruded elements simply keep
their position relatively to the <b>Base Point</b> at each their position relatively to the <b>Base Point</b> at each
@ -153,7 +155,7 @@ The following dialog will appear:
<b>Linear variation of the angles</b> option allows defining the angle <b>Linear variation of the angles</b> option allows defining the angle
of gradual rotation for the whole path. At each step the elements will of gradual rotation for the whole path. At each step the elements will
be rotated by <code>angle / nb. of steps</code>. be rotated by <code>( angle / nb. of steps )</code>.
</li> </li>
</ul> </ul>
</li> </li>

View File

@ -3228,7 +3228,6 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
list<const SMDS_MeshElement *>& removedNodes, list<const SMDS_MeshElement *>& removedNodes,
bool removenodes) bool removenodes)
{ {
//MESSAGE("SMDS_Mesh::RemoveElement " << elem->getVtkId() << " " << removenodes);
// get finite elements built on elem // get finite elements built on elem
set<const SMDS_MeshElement*> * s1; set<const SMDS_MeshElement*> * s1;
if ( (elem->GetType() == SMDSAbs_0DElement) if ( (elem->GetType() == SMDSAbs_0DElement)
@ -3273,19 +3272,16 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
// Remove element from <InverseElements> of its nodes // Remove element from <InverseElements> of its nodes
SMDS_ElemIteratorPtr itn = (*it)->nodesIterator(); SMDS_ElemIteratorPtr itn = (*it)->nodesIterator();
while (itn->more()) while (itn->more())
{ {
SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next())); SMDS_MeshNode * n = static_cast<SMDS_MeshNode *> (const_cast<SMDS_MeshElement *> (itn->next()));
n->RemoveInverseElement((*it)); n->RemoveInverseElement((*it));
} }
int IdToRemove = (*it)->GetID(); int IdToRemove = (*it)->GetID();
int vtkid = (*it)->getVtkId(); int vtkid = (*it)->getVtkId();
//MESSAGE("elem Id to remove " << IdToRemove << " vtkid " << vtkid <<
// " vtktype " << (*it)->GetVtkType() << " type " << (*it)->GetType());
switch ((*it)->GetType()) switch ((*it)->GetType())
{ {
case SMDSAbs_Node: case SMDSAbs_Node:
MYASSERT("Internal Error: This should not happen") MYASSERT("Internal Error: This should not happen");
;
break; break;
case SMDSAbs_0DElement: case SMDSAbs_0DElement:
if (IdToRemove >= 0) if (IdToRemove >= 0)
@ -3307,8 +3303,10 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
myElementIDFactory->ReleaseID(IdToRemove, vtkid); myElementIDFactory->ReleaseID(IdToRemove, vtkid);
if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it)) if (const SMDS_VtkEdge* vtkElem = dynamic_cast<const SMDS_VtkEdge*>(*it))
myEdgePool->destroy((SMDS_VtkEdge*) vtkElem); myEdgePool->destroy((SMDS_VtkEdge*) vtkElem);
else else {
((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
delete (*it); delete (*it);
}
break; break;
case SMDSAbs_Face: case SMDSAbs_Face:
if (IdToRemove >= 0) if (IdToRemove >= 0)
@ -3320,8 +3318,10 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
myElementIDFactory->ReleaseID(IdToRemove, vtkid); myElementIDFactory->ReleaseID(IdToRemove, vtkid);
if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it)) if (const SMDS_VtkFace* vtkElem = dynamic_cast<const SMDS_VtkFace*>(*it))
myFacePool->destroy((SMDS_VtkFace*) vtkElem); myFacePool->destroy((SMDS_VtkFace*) vtkElem);
else else {
((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
delete (*it); delete (*it);
}
break; break;
case SMDSAbs_Volume: case SMDSAbs_Volume:
if (IdToRemove >= 0) if (IdToRemove >= 0)
@ -3333,8 +3333,10 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
myElementIDFactory->ReleaseID(IdToRemove, vtkid); myElementIDFactory->ReleaseID(IdToRemove, vtkid);
if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it)) if (const SMDS_VtkVolume* vtkElem = dynamic_cast<const SMDS_VtkVolume*>(*it))
myVolumePool->destroy((SMDS_VtkVolume*) vtkElem); myVolumePool->destroy((SMDS_VtkVolume*) vtkElem);
else else {
((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
delete (*it); delete (*it);
}
break; break;
case SMDSAbs_Ball: case SMDSAbs_Ball:
if (IdToRemove >= 0) if (IdToRemove >= 0)
@ -3346,46 +3348,46 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem,
myElementIDFactory->ReleaseID(IdToRemove, vtkid); myElementIDFactory->ReleaseID(IdToRemove, vtkid);
if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it)) if (const SMDS_BallElement* vtkElem = dynamic_cast<const SMDS_BallElement*>(*it))
myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem )); myBallPool->destroy(const_cast<SMDS_BallElement*>( vtkElem ));
else else {
((SMDS_MeshElement*) *it)->init( -1, -1, -1 ); // avoid reuse
delete (*it); delete (*it);
}
break; break;
case SMDSAbs_All: case SMDSAbs_All: // avoid compilation warning
case SMDSAbs_NbElementTypes: break; case SMDSAbs_NbElementTypes: break;
} }
if (vtkid >= 0) if (vtkid >= 0)
{ {
//MESSAGE("VTK_EMPTY_CELL in " << vtkid); this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL);
this->myGrid->GetCellTypesArray()->SetValue(vtkid, VTK_EMPTY_CELL); }
}
it++; it++;
} }
// remove exclusive (free) nodes // remove exclusive (free) nodes
if (removenodes) if (removenodes)
{
it = s2->begin();
while (it != s2->end())
{ {
it = s2->begin(); int IdToRemove = (*it)->GetID();
while (it != s2->end()) if (IdToRemove >= 0)
{ {
int IdToRemove = (*it)->GetID(); myNodes[IdToRemove] = 0;
//MESSAGE( "SMDS: RM node " << IdToRemove); myInfo.myNbNodes--;
if (IdToRemove >= 0) }
{ myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId());
myNodes[IdToRemove] = 0; removedNodes.push_back((*it));
myInfo.myNbNodes--; if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it))
} {
myNodeIDFactory->ReleaseID((*it)->GetID(), (*it)->getVtkId()); ((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition());
removedNodes.push_back((*it)); myNodePool->destroy((SMDS_MeshNode*) vtkElem);
if (const SMDS_MeshNode* vtkElem = dynamic_cast<const SMDS_MeshNode*>(*it)) }
{ else
((SMDS_MeshNode*)vtkElem)->SetPosition(SMDS_SpacePosition::originSpacePosition()); delete (*it);
myNodePool->destroy((SMDS_MeshNode*) vtkElem); it++;
}
else
delete (*it);
it++;
}
} }
}
delete s2; delete s2;
delete s1; delete s1;
@ -3430,11 +3432,12 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
} }
// in meshes without descendants elements are always free // in meshes without descendants elements are always free
switch (aType) { switch (aType) {
case SMDSAbs_0DElement: case SMDSAbs_0DElement:
myCells[elemId] = 0; myCells[elemId] = 0;
myInfo.remove(elem); myInfo.remove(elem);
delete elem; delete elem;
elem = 0;
break; break;
case SMDSAbs_Edge: case SMDSAbs_Edge:
myCells[elemId] = 0; myCells[elemId] = 0;
@ -3463,6 +3466,9 @@ void SMDS_Mesh::RemoveFreeElement(const SMDS_MeshElement * elem)
this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL); this->myGrid->GetCellTypesArray()->SetValue(vtkId, VTK_EMPTY_CELL);
// --- to do: keep vtkid in a list of reusable cells // --- to do: keep vtkid in a list of reusable cells
if ( elem )
((SMDS_MeshElement*) elem)->init( -1, -1, -1 ); // avoid reuse
} }
} }

View File

@ -182,17 +182,14 @@ public:
MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element"); MESSAGE("SMDS_MeshNode_MyInvIterator problem Null element");
throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element"); throw SALOME_Exception("SMDS_MeshNode_MyInvIterator problem Null element");
} }
//MESSAGE("vtkId " << vtkId << " smdsId " << smdsId << " " << elem->GetType());
iter++; iter++;
return elem; return elem;
} }
}; };
SMDS_ElemIteratorPtr SMDS_MeshNode:: SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const
GetInverseElementIterator(SMDSAbs_ElementType type) const
{ {
vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID); vtkCellLinks::Link l = SMDS_Mesh::_meshList[myMeshId]->getGrid()->GetCellLinks()->GetLink(myVtkID);
//MESSAGE("myID " << myID << " ncells " << l.ncells);
return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type)); return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(SMDS_Mesh::_meshList[myMeshId], l.cells, l.ncells, type));
} }

View File

@ -2939,14 +2939,13 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
SMESH_MesherHelper helper( *GetMesh() ); SMESH_MesherHelper helper( *GetMesh() );
TIDSortedElemSet::iterator itElem; TIDSortedElemSet::iterator itElem;
for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
{
const SMDS_MeshElement* elem = *itElem; const SMDS_MeshElement* elem = *itElem;
if ( !elem || elem->GetType() != SMDSAbs_Face ) if ( !elem || elem->GetGeomType() != SMDSGeom_QUADRANGLE )
continue; continue;
bool isquad = elem->NbNodes()==4 || elem->NbNodes()==8;
if(!isquad) continue;
if(elem->NbNodes()==4) { if ( elem->NbNodes() == 4 ) {
// retrieve element nodes // retrieve element nodes
const SMDS_MeshNode* aNodes [4]; const SMDS_MeshNode* aNodes [4];
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
@ -2969,10 +2968,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
myLastCreatedElems.Append(newElem2); myLastCreatedElems.Append(newElem2);
// put a new triangle on the same shape and add to the same groups // put a new triangle on the same shape and add to the same groups
if ( aShapeId ) if ( aShapeId )
{ {
aMesh->SetMeshElementOnShape( newElem1, aShapeId ); aMesh->SetMeshElementOnShape( newElem1, aShapeId );
aMesh->SetMeshElementOnShape( newElem2, aShapeId ); aMesh->SetMeshElementOnShape( newElem2, aShapeId );
} }
AddToSameGroups( newElem1, elem, aMesh ); AddToSameGroups( newElem1, elem, aMesh );
AddToSameGroups( newElem2, elem, aMesh ); AddToSameGroups( newElem2, elem, aMesh );
aMesh->RemoveElement( elem ); aMesh->RemoveElement( elem );
@ -2980,8 +2979,8 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
// Quadratic quadrangle // Quadratic quadrangle
if( elem->NbNodes()==8 && elem->IsQuadratic() ) { else if ( elem->NbNodes() == 8 )
{
// get surface elem is on // get surface elem is on
int aShapeId = FindShape( elem ); int aShapeId = FindShape( elem );
if ( aShapeId != helper.GetSubShapeID() ) { if ( aShapeId != helper.GetSubShapeID() ) {
@ -3001,14 +3000,14 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
const SMDS_MeshNode* inFaceNode = 0; const SMDS_MeshNode* inFaceNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator(); SMDS_ElemIteratorPtr itN = elem->nodesIterator();
int i = 0; int i = 0;
while ( itN->more() ) { if ( helper.GetNodeUVneedInFaceNode() )
aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() ); while ( itN->more() && !inFaceNode ) {
if ( !inFaceNode && helper.GetNodeUVneedInFaceNode() && aNodes[ i++ ] = static_cast<const SMDS_MeshNode*>( itN->next() );
aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE ) if ( aNodes[ i-1 ]->GetPosition()->GetTypeOfPosition() == SMDS_TOP_FACE )
{ {
inFaceNode = aNodes[ i-1 ]; inFaceNode = aNodes[ i-1 ];
}
} }
}
// find middle point for (0,1,2,3) // find middle point for (0,1,2,3)
// and create a node in this point; // and create a node in this point;
@ -3048,10 +3047,10 @@ bool SMESH_MeshEditor::QuadToTri (TIDSortedElemSet & theElems,
myLastCreatedElems.Append(newElem2); myLastCreatedElems.Append(newElem2);
// put a new triangle on the same shape and add to the same groups // put a new triangle on the same shape and add to the same groups
if ( aShapeId ) if ( aShapeId )
{ {
aMesh->SetMeshElementOnShape( newElem1, aShapeId ); aMesh->SetMeshElementOnShape( newElem1, aShapeId );
aMesh->SetMeshElementOnShape( newElem2, aShapeId ); aMesh->SetMeshElementOnShape( newElem2, aShapeId );
} }
AddToSameGroups( newElem1, elem, aMesh ); AddToSameGroups( newElem1, elem, aMesh );
AddToSameGroups( newElem2, elem, aMesh ); AddToSameGroups( newElem2, elem, aMesh );
aMesh->RemoveElement( elem ); aMesh->RemoveElement( elem );

View File

@ -894,16 +894,7 @@ void SMESHDS_Mesh::RemoveNode(const SMDS_MeshNode * n)
{ {
if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces())) if ( n->NbInverseElements() == 0 && !(hasConstructionEdges() || hasConstructionFaces()))
{ {
SMESHDS_SubMesh* subMesh = MeshElements( n->getshapeId() ); RemoveFreeNode( n, 0, true );
SMESHDS_SubMeshIteratorPtr subIt;
if ( !subMesh )
subIt = SubMeshes();
for ( ; !subMesh && subIt->more(); ) {
subMesh = const_cast< SMESHDS_SubMesh* >( subIt->next() );
if ( subMesh->IsComplexSubmesh() || !subMesh->Contains( n ))
subMesh = 0;
}
RemoveFreeNode( n, subMesh, true);
return; return;
} }

View File

@ -117,13 +117,22 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele
{ {
if (!ME) if (!ME)
{ {
MESSAGE("-----------------> Remove Null Element " << isElemDeleted);
return false; return false;
} }
if (!IsComplexSubmesh()) if (!IsComplexSubmesh())
{ {
if ( ME->getshapeId() != myIndex ) if ( ME->getshapeId() != myIndex ) // elem not in a pool can loose it's data already
{
if ( isElemDeleted )
for ( size_t i = 0; i < myElements.size(); ++i )
if ( myElements[i] == ME )
{
myElements[i] = 0;
++myUnusedIdElements;
return true;
}
return false; return false;
}
int idInSubShape = ME->getIdInShape(); int idInSubShape = ME->getIdInShape();
SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME); SMDS_MeshElement* elem = (SMDS_MeshElement*) (ME);
elem->setShapeId(0); elem->setShapeId(0);
@ -140,7 +149,6 @@ bool SMESHDS_SubMesh::RemoveElement(const SMDS_MeshElement * ME, bool isElemDele
} }
return false; return false;
} }
MESSAGE("Try to remove an element from a complex submesh ");
return false; return false;
} }
@ -182,7 +190,17 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
if (!IsComplexSubmesh()) if (!IsComplexSubmesh())
{ {
if ( N->getshapeId() != myIndex ) if ( N->getshapeId() != myIndex )
{
if ( isNodeDeleted )
for ( size_t i = 0; i < myNodes.size(); ++i )
if ( myNodes[i] == N )
{
myNodes[i] = 0;
++myUnusedIdNodes;
return true;
}
return false; return false;
}
int idInSubShape = N->getIdInShape(); int idInSubShape = N->getIdInShape();
SMDS_MeshNode* node = (SMDS_MeshNode*) (N); SMDS_MeshNode* node = (SMDS_MeshNode*) (N);
node->setShapeId(0); node->setShapeId(0);
@ -199,13 +217,12 @@ bool SMESHDS_SubMesh::RemoveNode(const SMDS_MeshNode * N, bool isNodeDeleted)
} }
return false; return false;
} }
MESSAGE("Try to remove a node from a complex submesh");
return false; return false;
} }
//======================================================================= //=======================================================================
//function : NbElements //function : NbElements
//purpose : //purpose :
//======================================================================= //=======================================================================
int SMESHDS_SubMesh::NbElements() const int SMESHDS_SubMesh::NbElements() const

View File

@ -1134,9 +1134,10 @@ void SMESHGUI_ClippingDlg::updateActorItem( QListWidgetItem* theItem,
anActorList.remove( anActor ); anActorList.remove( anActor );
if( SMESH::ComputeBounds( anActorList, myBounds ) ) { if( SMESH::ComputeBounds( anActorList, myBounds ) ) {
myPreviewWidget->On();
myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2], myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2],
myBounds[3], myBounds[4], myBounds[5] ); myBounds[3], myBounds[4], myBounds[5] );
if( PreviewCheckBox->isChecked() )
myPreviewWidget->On();
} }
else else
myPreviewWidget->Off(); myPreviewWidget->Off();
@ -1249,9 +1250,10 @@ void SMESHGUI_ClippingDlg::ClickOnNew()
bool anIsBlocked = ActorList->blockSignals( true ); bool anIsBlocked = ActorList->blockSignals( true );
if( SMESH::ComputeBounds( anActorList, myBounds ) ) { if( SMESH::ComputeBounds( anActorList, myBounds ) ) {
myPreviewWidget->On();
myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2], myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2],
myBounds[3], myBounds[4], myBounds[5] ); myBounds[3], myBounds[4], myBounds[5] );
if( PreviewCheckBox->isChecked() )
myPreviewWidget->On();
} }
else else
myPreviewWidget->Off(); myPreviewWidget->Off();
@ -1342,9 +1344,10 @@ void SMESHGUI_ClippingDlg::onSelectPlane ( int theIndex )
myIsSelectPlane = false; myIsSelectPlane = false;
if( SMESH::ComputeBounds( aPlaneData.ActorList, myBounds ) ) { if( SMESH::ComputeBounds( aPlaneData.ActorList, myBounds ) ) {
myPreviewWidget->On();
myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2], myPreviewWidget->PlaceWidget( myBounds[0], myBounds[1], myBounds[2],
myBounds[3], myBounds[4], myBounds[5] ); myBounds[3], myBounds[4], myBounds[5] );
if( PreviewCheckBox->isChecked() )
myPreviewWidget->On();
} }
else else
myPreviewWidget->Off(); myPreviewWidget->Off();

View File

@ -224,7 +224,7 @@ void SMESHGUI_MeshOp::startOperation()
} }
} }
SMESHGUI_SelectionOp::startOperation(); SMESHGUI_SelectionOp::startOperation();
// iterate through dimensions and get available algoritms, set them to the dialog // iterate through dimensions and get available algorithms, set them to the dialog
_PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" ); _PTR(SComponent) aFather = SMESH::GetActiveStudyDocument()->FindComponent( "SMESH" );
for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ ) for ( int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++ )
{ {
@ -1481,14 +1481,6 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
if (aDim == -1) if (aDim == -1)
return; return;
// find highest available dimension, all algos of this dimension are available for choice
int aTopDim = -1;
for (int i = SMESH::DIM_0D; i <= SMESH::DIM_3D; i++)
if (isAccessibleDim( i ))
aTopDim = i;
if (aTopDim == -1)
return;
const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh )); const bool isSubmesh = ( myToCreate ? !myIsMesh : myDlg->isObjectShown( SMESHGUI_MeshDlg::Mesh ));
HypothesisData* algoData = hypData( aDim, Algo, theIndex ); HypothesisData* algoData = hypData( aDim, Algo, theIndex );
@ -1497,22 +1489,24 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
QStringList anAvailable; QStringList anAvailable;
// check that tab enabled of one less dimension // enable / disable tabs
if ( aDim > SMESH::DIM_0D ) if ( myIsOnGeometry ) {
{ for (int i = SMESH::DIM_3D; i >= SMESH::DIM_0D; i--) {
if ( myIsOnGeometry ) { if ( i > aDim ) {
QString anCompareType = currentMeshTypeName(myDlg->currentMeshType()); if ( i > myMaxShapeDim ) myDlg->disableTab( i );
bool is2dtype = ( anCompareType == "QUAD" ) || ( anCompareType == "TRIA" ); else myDlg->enableTab( i );
int dim = is2dtype ? SMESH::DIM_2D : SMESH::DIM_3D; }
for (int i = dim; i >= SMESH::DIM_0D; i--) { else if ( i == aDim ) {
if ( i != aDim ) { continue;
if ( algoData && algoData->InputTypes.isEmpty() ) { }
myDlg->disableTab( i ); else {//( i < aDim )
setCurrentHyp(i, Algo, -1); if ( algoData && algoData->InputTypes.isEmpty() ) {
} myDlg->disableTab( i );
else { for ( int type = Algo, nbTypes = nbDlgHypTypes(i); type < nbTypes; type++ )
myDlg->enableTab( i ); setCurrentHyp(i, type, -1);
} }
else {
myDlg->enableTab( i );
} }
} }
} }
@ -1557,7 +1551,7 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
nextAlgo = 0; nextAlgo = 0;
} }
// set new available algoritms // set new available algorithms
availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType); availableHyps( dim, Algo, anAvailable, myAvailableHypData[dim][Algo], prevAlgo, nextAlgo, anCurrentCompareType);
HypothesisData* soleCompatible = 0; HypothesisData* soleCompatible = 0;
if ( anAvailable.count() == 1 ) if ( anAvailable.count() == 1 )
@ -1567,13 +1561,15 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo ); algoIndex = myAvailableHypData[dim][Algo].indexOf( curAlgo );
if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) { if ( !isSubmesh && algoIndex < 0 && soleCompatible && !forward && dim != SMESH::DIM_0D) {
// select the sole compatible algo // select the sole compatible algo
algoIndex = myAvailableHypData[dim][Algo].indexOf( soleCompatible ); algoIndex = 0;
} }
setCurrentHyp( dim, Algo, algoIndex); setCurrentHyp( dim, Algo, algoIndex );
// remember current algo // remember current algo
prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex ); prevAlgo = algoByDim[ dim ] = hypData( dim, Algo, algoIndex );
}
} // loop on dims
if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D ) if ( myMaxShapeDim == SMESH::DIM_3D && forward && algoDim == SMESH::DIM_1D )
{ {
algoDim = SMESH::DIM_3D; algoDim = SMESH::DIM_3D;
@ -1581,9 +1577,10 @@ void SMESHGUI_MeshOp::onAlgoSelected( const int theIndex,
a3DAlgo = prevAlgo; a3DAlgo = prevAlgo;
continue; continue;
} }
} } // loops backward and forward
// set hypotheses corresponding to the found algoritms
// set hypotheses corresponding to the found algorithms
_PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
@ -2117,7 +2114,7 @@ SMESH::SMESH_Hypothesis_var SMESHGUI_MeshOp::getAlgo( const int theDim )
return anAlgoVar; return anAlgoVar;
QString aHypName = dataList[ aHypIndex ]->TypeName; QString aHypName = dataList[ aHypIndex ]->TypeName;
// get existing algoritms // get existing algorithms
_PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH"); _PTR(SObject) pObj = SMESH::GetActiveStudyDocument()->FindComponent("SMESH");
QStringList tmp; QStringList tmp;
existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]); existingHyps( theDim, Algo, pObj, tmp, myExistingHyps[ theDim ][ Algo ]);
@ -2397,7 +2394,7 @@ bool SMESHGUI_MeshOp::editMeshOrSubMesh( QString& theMess )
// Assign new algorithms and hypotheses // Assign new algorithms and hypotheses
for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ ) for ( int dim = aDim; dim <= SMESH::DIM_3D; dim++ )
{ {
if ( !isAccessibleDim( dim )) continue; //if ( !isAccessibleDim( dim )) continue;
// find or create algorithm // find or create algorithm
SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim ); SMESH::SMESH_Hypothesis_var anAlgoVar = getAlgo( dim );
@ -2746,18 +2743,14 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
setCurrentHyp( dim, Algo, anCurrentAvailableAlgo ); setCurrentHyp( dim, Algo, anCurrentAvailableAlgo );
} }
if ( aDim == SMESH::DIM_2D) { for ( int i = myMaxShapeDim; i >= SMESH::DIM_0D; i-- ) {
myDlg->disableTab( SMESH::DIM_3D );
setCurrentHyp( SMESH::DIM_3D, Algo, -1);
}
for ( int i = myMaxShapeDim; i > SMESH::DIM_0D; i-- ) {
bool isNoneAlg = currentHyp( i, Algo ) < 0; bool isNoneAlg = currentHyp( i, Algo ) < 0;
if ( !isNoneAlg ) if ( !isNoneAlg )
isReqDisBound = myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty(); isReqDisBound = myAvailableHypData[i][Algo].at( currentHyp( i, Algo ) )->InputTypes.isEmpty();
else else
isReqDisBound = true; isReqDisBound = true;
if ( isReqDisBound && !isNoneAlg) { if ( isReqDisBound && !isNoneAlg && i <= aDim) {
for (int j = i; j >= SMESH::DIM_0D; j--) { for (int j = myMaxShapeDim; j >= SMESH::DIM_0D; j--) {
if ( currentHyp( j, Algo ) < 0 ) { if ( currentHyp( j, Algo ) < 0 ) {
myDlg->disableTab( j ); myDlg->disableTab( j );
setCurrentHyp( j , Algo, -1 ); setCurrentHyp( j , Algo, -1 );
@ -2765,7 +2758,15 @@ void SMESHGUI_MeshOp::setFilteredAlgoData( const int theTabIndex, const int theI
} }
break; break;
} }
else {
myDlg->enableTab( i );
}
} }
if ( aDim == SMESH::DIM_2D) {
myDlg->disableTab( SMESH::DIM_3D );
setCurrentHyp( SMESH::DIM_3D, Algo, -1);
}
int currentTab = ( theTabIndex <= aDim ) ? theTabIndex : aDim; int currentTab = ( theTabIndex <= aDim ) ? theTabIndex : aDim;
myDlg->setCurrentTab( currentTab ); myDlg->setCurrentTab( currentTab );
} }

View File

@ -42,6 +42,7 @@
#include <SUIT_Desktop.h> #include <SUIT_Desktop.h>
#include <SUIT_Session.h> #include <SUIT_Session.h>
#include <SUIT_MessageBox.h> #include <SUIT_MessageBox.h>
#include <SUIT_OverrideCursor.h>
#include <LightApp_Application.h> #include <LightApp_Application.h>
#include <LightApp_SelectionMgr.h> #include <LightApp_SelectionMgr.h>
@ -225,7 +226,10 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
if (mySMESHGUI->isActiveStudyLocked()) if (mySMESHGUI->isActiveStudyLocked())
return; return;
if (myNbOkElements) { if (myNbOkElements)
{
SUIT_OverrideCursor wc;
QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts); QStringList aListId = myEditCurrentArgument->text().split(" ", QString::SkipEmptyParts);
SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array; SMESH::long_array_var anArrayOfIdeces = new SMESH::long_array;
anArrayOfIdeces->length(aListId.count()); anArrayOfIdeces->length(aListId.count());
@ -233,7 +237,8 @@ void SMESHGUI_RemoveElementsDlg::ClickOnApply()
anArrayOfIdeces[i] = aListId[ i ].toInt(); anArrayOfIdeces[i] = aListId[ i ].toInt();
bool aResult = false; bool aResult = false;
try { try
{
SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor();
aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in()); aResult = aMeshEditor->RemoveElements(anArrayOfIdeces.in());

View File

@ -458,6 +458,10 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
void GetElementsNearLine( const gp_Ax1& line, void GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type, SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems); vector< const SMDS_MeshElement* >& foundElems);
void GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems);
double getTolerance(); double getTolerance();
bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face, bool getIntersParamOnLine(const gp_Lin& line, const SMDS_MeshElement* face,
const double tolerance, double & param); const double tolerance, double & param);
@ -466,6 +470,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
{ {
return _outerFaces.empty() || _outerFaces.count(face); return _outerFaces.empty() || _outerFaces.count(face);
} }
struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState()) struct TInters //!< data of intersection of the line and the mesh face (used in GetPointState())
{ {
const SMDS_MeshElement* _face; const SMDS_MeshElement* _face;
@ -646,6 +651,7 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin(); set< const SMDS_MeshElement*, TIDCompare >::const_iterator face = faces.begin();
for ( ; face != faces.end(); ++face ) for ( ; face != faces.end(); ++face )
{ {
if ( *face == outerFace ) continue;
if ( !SMESH_MeshAlgos::FaceNormal( *face, fNorm, /*normalized=*/false )) if ( !SMESH_MeshAlgos::FaceNormal( *face, fNorm, /*normalized=*/false ))
continue; continue;
gp_Vec dirInF = gp_Vec( fNorm ) ^ n1n2; gp_Vec dirInF = gp_Vec( fNorm ) ^ n1n2;
@ -660,8 +666,8 @@ void SMESH_ElementSearcherImpl::findOuterBoundary(const SMDS_MeshElement* outerF
// store the found outer face and add its links to continue seaching from // store the found outer face and add its links to continue seaching from
if ( outerFace2 ) if ( outerFace2 )
{ {
_outerFaces.insert( outerFace ); _outerFaces.insert( outerFace2 );
int nbNodes = outerFace2->NbNodes()/( outerFace2->IsQuadratic() ? 2 : 1 ); int nbNodes = outerFace2->NbCornerNodes();
for ( int i = 0; i < nbNodes; ++i ) for ( int i = 0; i < nbNodes; ++i )
{ {
SMESH_TLink link2( outerFace2->GetNode(i), outerFace2->GetNode((i+1)%nbNodes)); SMESH_TLink link2( outerFace2->GetNode(i), outerFace2->GetNode((i+1)%nbNodes));
@ -1078,6 +1084,27 @@ void SMESH_ElementSearcherImpl::GetElementsNearLine( const gp_Ax1&
foundElems.assign( suspectFaces.begin(), suspectFaces.end()); foundElems.assign( suspectFaces.begin(), suspectFaces.end());
} }
//=======================================================================
/*
* Return elements whose bounding box intersects a sphere
*/
//=======================================================================
void SMESH_ElementSearcherImpl::GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
vector< const SMDS_MeshElement* >& foundElems)
{
if ( !_ebbTree || _elementType != type )
{
if ( _ebbTree ) delete _ebbTree;
_ebbTree = new ElementBndBoxTree( *_mesh, _elementType = type, _meshPartIt );
}
TIDSortedElemSet suspectFaces; // elements possibly intersecting the line
_ebbTree->getElementsInSphere( center, radius, suspectFaces );
foundElems.assign( suspectFaces.begin(), suspectFaces.end() );
}
//======================================================================= //=======================================================================
/*! /*!
* \brief Return true if the point is IN or ON of the element * \brief Return true if the point is IN or ON of the element

View File

@ -88,6 +88,13 @@ struct SMESHUtils_EXPORT SMESH_ElementSearcher
virtual void GetElementsNearLine( const gp_Ax1& line, virtual void GetElementsNearLine( const gp_Ax1& line,
SMDSAbs_ElementType type, SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems) = 0; std::vector< const SMDS_MeshElement* >& foundElems) = 0;
/*!
* \brief Return elements whose bounding box intersects a sphere
*/
virtual void GetElementsInSphere( const gp_XYZ& center,
const double radius,
SMDSAbs_ElementType type,
std::vector< const SMDS_MeshElement* >& foundElems) = 0;
/*! /*!
* \brief Find out if the given point is out of closed 2D mesh. * \brief Find out if the given point is out of closed 2D mesh.
*/ */

View File

@ -339,7 +339,7 @@ namespace {
// gravity center of a layer // gravity center of a layer
gp_XYZ O(0,0,0); gp_XYZ O(0,0,0);
int vertexCol = -1; int vertexCol = -1;
for ( int i = 0; i < columns.size(); ++i ) for ( size_t i = 0; i < columns.size(); ++i )
{ {
O += gpXYZ( (*columns[ i ])[ z ]); O += gpXYZ( (*columns[ i ])[ z ]);
if ( vertexCol < 0 && if ( vertexCol < 0 &&
@ -351,7 +351,7 @@ namespace {
// Z axis // Z axis
gp_Vec Z(0,0,0); gp_Vec Z(0,0,0);
int iPrev = columns.size()-1; int iPrev = columns.size()-1;
for ( int i = 0; i < columns.size(); ++i ) for ( size_t i = 0; i < columns.size(); ++i )
{ {
gp_Vec v1( O, gpXYZ( (*columns[ iPrev ])[ z ])); gp_Vec v1( O, gpXYZ( (*columns[ iPrev ])[ z ]));
gp_Vec v2( O, gpXYZ( (*columns[ i ] )[ z ])); gp_Vec v2( O, gpXYZ( (*columns[ i ] )[ z ]));
@ -363,11 +363,11 @@ namespace {
{ {
O = gpXYZ( (*columns[ vertexCol ])[ z ]); O = gpXYZ( (*columns[ vertexCol ])[ z ]);
} }
if ( xColumn < 0 || xColumn >= columns.size() ) if ( xColumn < 0 || xColumn >= (int) columns.size() )
{ {
// select a column for X dir // select a column for X dir
double maxDist = 0; double maxDist = 0;
for ( int i = 0; i < columns.size(); ++i ) for ( size_t i = 0; i < columns.size(); ++i )
{ {
double dist = ( O - gpXYZ((*columns[ i ])[ z ])).SquareModulus(); double dist = ( O - gpXYZ((*columns[ i ])[ z ])).SquareModulus();
if ( dist > maxDist ) if ( dist > maxDist )
@ -454,9 +454,9 @@ namespace {
std::advance( edgeIt, nbEdges-1 ); std::advance( edgeIt, nbEdges-1 );
TopoDS_Edge prevE = *edgeIt; TopoDS_Edge prevE = *edgeIt;
// bool isPrevStraight = SMESH_Algo::IsStraight( prevE ); // bool isPrevStraight = SMESH_Algo::IsStraight( prevE );
int iPrev = nbEdges - 1; // int iPrev = nbEdges - 1;
int iUnite = -1; // the first of united EDGEs // int iUnite = -1; // the first of united EDGEs
// analyse angles between EDGEs // analyse angles between EDGEs
int nbCorners = 0; int nbCorners = 0;
@ -524,7 +524,7 @@ namespace {
void pointsToPython(const std::vector<gp_XYZ>& p) void pointsToPython(const std::vector<gp_XYZ>& p)
{ {
#ifdef _DEBUG_ #ifdef _DEBUG_
for ( int i = SMESH_Block::ID_V000; i < p.size(); ++i ) for ( size_t i = SMESH_Block::ID_V000; i < p.size(); ++i )
{ {
cout << "mesh.AddNode( " << p[i].X() << ", "<< p[i].Y() << ", "<< p[i].Z() << ") # " << i <<" " ; cout << "mesh.AddNode( " << p[i].X() << ", "<< p[i].Y() << ", "<< p[i].Z() << ") # " << i <<" " ;
SMESH_Block::DumpShapeID( i, cout ) << endl; SMESH_Block::DumpShapeID( i, cout ) << endl;
@ -933,6 +933,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin(); list< TopoDS_Edge >::iterator edge = thePrism.myBottomEdges.begin();
std::list< int >::iterator nbE = thePrism.myNbEdgesInWires.begin(); std::list< int >::iterator nbE = thePrism.myNbEdgesInWires.begin();
std::list< int > nbQuadsPerWire;
int iE = 0; int iE = 0;
double f,l; double f,l;
while ( edge != thePrism.myBottomEdges.end() ) while ( edge != thePrism.myBottomEdges.end() )
@ -976,6 +977,8 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
{ {
iE = 0; iE = 0;
++nbE; ++nbE;
int nbQuadPrev = nbQuadsPerWire.empty() ? 0 : nbQuadsPerWire.back();
nbQuadsPerWire.push_back( thePrism.myWallQuads.size() - nbQuadPrev );
} }
} }
@ -987,12 +990,14 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
// that is not so evident in case of several WIREs in the bottom FACE // that is not so evident in case of several WIREs in the bottom FACE
thePrism.myRightQuadIndex.clear(); thePrism.myRightQuadIndex.clear();
for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i ) for ( size_t i = 0; i < thePrism.myWallQuads.size(); ++i )
thePrism.myRightQuadIndex.push_back( i+1 );
list< int >::iterator nbEinW = thePrism.myNbEdgesInWires.begin();
for ( int iLeft = 0; nbEinW != thePrism.myNbEdgesInWires.end(); ++nbEinW )
{ {
thePrism.myRightQuadIndex[ iLeft + *nbEinW - 1 ] = iLeft; // 1st EDGE index of a current WIRE thePrism.myRightQuadIndex.push_back( i+1 ); // OK for all but the last EDGE of a WIRE
iLeft += *nbEinW; }
list< int >::iterator nbQinW = nbQuadsPerWire.begin();
for ( int iLeft = 0; nbQinW != nbQuadsPerWire.end(); ++nbQinW )
{
thePrism.myRightQuadIndex[ iLeft + *nbQinW - 1 ] = iLeft; // for the last EDGE of a WIRE
iLeft += *nbQinW;
} }
while ( totalNbFaces - faceMap.Extent() > 2 ) while ( totalNbFaces - faceMap.Extent() > 2 )
@ -1072,7 +1077,7 @@ bool StdMeshers_Prism_3D::getWallFaces( Prism_3D::TPrismTopo & thePrism,
{ {
// now only top and bottom FACEs are not in the faceMap // now only top and bottom FACEs are not in the faceMap
faceMap.Add( thePrism.myBottom ); faceMap.Add( thePrism.myBottom );
for ( TopExp_Explorer f( thePrism.myShape3D, TopAbs_FACE );f.More(); f.Next() ) for ( TopExp_Explorer f( thePrism.myShape3D, TopAbs_FACE ); f.More(); f.Next() )
if ( !faceMap.Contains( f.Current() )) { if ( !faceMap.Contains( f.Current() )) {
thePrism.myTop = TopoDS::Face( f.Current() ); thePrism.myTop = TopoDS::Face( f.Current() );
break; break;
@ -1975,7 +1980,7 @@ bool StdMeshers_Prism_3D::assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf
n2nMapPtr = & TProjction2dAlgo::instance( this )->GetNodesMap(); n2nMapPtr = & TProjction2dAlgo::instance( this )->GetNodesMap();
} }
if ( !n2nMapPtr || n2nMapPtr->size() < botSMDS->NbNodes() ) if ( !n2nMapPtr || (int) n2nMapPtr->size() < botSMDS->NbNodes() )
{ {
// associate top and bottom faces // associate top and bottom faces
NSProjUtils::TShapeShapeMap shape2ShapeMap; NSProjUtils::TShapeShapeMap shape2ShapeMap;
@ -2510,6 +2515,8 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
int _nbCheckedEdges; // nb of EDGEs whose location is defined int _nbCheckedEdges; // nb of EDGEs whose location is defined
PrismSide *_leftSide; PrismSide *_leftSide;
PrismSide *_rightSide; PrismSide *_rightSide;
void SetExcluded() { _leftSide = _rightSide = NULL; }
bool IsExcluded() const { return !_leftSide; }
const TopoDS_Edge& Edge( int i ) const const TopoDS_Edge& Edge( int i ) const
{ {
return (*_edges)[ i ]._edge; return (*_edges)[ i ]._edge;
@ -2571,16 +2578,34 @@ namespace // utils used by StdMeshers_Prism_3D::IsApplicable()
/*! /*!
* \brief Return another faces sharing an edge * \brief Return another faces sharing an edge
*/ */
const TopoDS_Shape & getAnotherFace( const TopoDS_Face& face, const TopoDS_Face & getAnotherFace( const TopoDS_Face& face,
const TopoDS_Edge& edge, const TopoDS_Edge& edge,
TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge) TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge)
{ {
TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edge )); TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edge ));
for ( ; faceIt.More(); faceIt.Next() ) for ( ; faceIt.More(); faceIt.Next() )
if ( !face.IsSame( faceIt.Value() )) if ( !face.IsSame( faceIt.Value() ))
return faceIt.Value(); return TopoDS::Face( faceIt.Value() );
return face; return face;
} }
//--------------------------------------------------------------------------------
/*!
* \brief Return number of faces sharing given edges
*/
int nbAdjacentFaces( const std::vector< EdgeWithNeighbors >& edges,
const TopTools_IndexedDataMapOfShapeListOfShape& facesOfEdge )
{
TopTools_MapOfShape adjFaces;
for ( size_t i = 0; i < edges.size(); ++i )
{
TopTools_ListIteratorOfListOfShape faceIt( facesOfEdge.FindFromKey( edges[i]._edge ));
for ( ; faceIt.More(); faceIt.Next() )
adjFaces.Add( faceIt.Value() );
}
return adjFaces.Extent();
}
} }
//================================================================================ //================================================================================
@ -2646,11 +2671,13 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA
typedef vector< EdgeWithNeighbors > TEdgeWithNeighborsVec; typedef vector< EdgeWithNeighbors > TEdgeWithNeighborsVec;
vector< TEdgeWithNeighborsVec > faceEdgesVec( allFaces.Extent() + 1 ); vector< TEdgeWithNeighborsVec > faceEdgesVec( allFaces.Extent() + 1 );
TopTools_IndexedMapOfShape* facesOfSide = new TopTools_IndexedMapOfShape[ faceEdgesVec.size() ]; const size_t nbEdgesMax = facesOfEdge.Extent() * 2; // there can be seam EDGES
TopTools_IndexedMapOfShape* facesOfSide = new TopTools_IndexedMapOfShape[ nbEdgesMax ];
SMESHUtils::ArrayDeleter<TopTools_IndexedMapOfShape> delFacesOfSide( facesOfSide ); SMESHUtils::ArrayDeleter<TopTools_IndexedMapOfShape> delFacesOfSide( facesOfSide );
// try to use each face as a bottom one // try to use each face as a bottom one
bool prismDetected = false; bool prismDetected = false;
vector< PrismSide > sides;
for ( int iF = 1; iF < allFaces.Extent() && !prismDetected; ++iF ) for ( int iF = 1; iF < allFaces.Extent() && !prismDetected; ++iF )
{ {
const TopoDS_Face& botF = TopoDS::Face( allFaces( iF )); const TopoDS_Face& botF = TopoDS::Face( allFaces( iF ));
@ -2663,11 +2690,12 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA
continue; // all faces are adjacent to botF - no top FACE continue; // all faces are adjacent to botF - no top FACE
// init data of side FACEs // init data of side FACEs
vector< PrismSide > sides( botEdges.size() ); sides.clear();
for ( int iS = 0; iS < botEdges.size(); ++iS ) sides.resize( botEdges.size() );
for ( size_t iS = 0; iS < botEdges.size(); ++iS )
{ {
sides[ iS ]._topEdge = botEdges[ iS ]._edge; sides[ iS ]._topEdge = botEdges[ iS ]._edge;
sides[ iS ]._face = botF; sides[ iS ]._face = botF;
sides[ iS ]._leftSide = & sides[ botEdges[ iS ]._iR ]; sides[ iS ]._leftSide = & sides[ botEdges[ iS ]._iR ];
sides[ iS ]._rightSide = & sides[ botEdges[ iS ]._iL ]; sides[ iS ]._rightSide = & sides[ botEdges[ iS ]._iL ];
sides[ iS ]._faces = & facesOfSide[ iS ]; sides[ iS ]._faces = & facesOfSide[ iS ];
@ -2699,8 +2727,8 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA
if ( side._isCheckedEdge[ iE ] ) continue; if ( side._isCheckedEdge[ iE ] ) continue;
const TopoDS_Edge& vertE = side.Edge( iE ); const TopoDS_Edge& vertE = side.Edge( iE );
const TopoDS_Shape& neighborF = getAnotherFace( side._face, vertE, facesOfEdge ); const TopoDS_Shape& neighborF = getAnotherFace( side._face, vertE, facesOfEdge );
bool isEdgeShared = adjSide->IsSideFace( neighborF ); bool isEdgeShared = adjSide->IsSideFace( neighborF );
if ( isEdgeShared ) if ( isEdgeShared ) // vertE is shared with adjSide
{ {
isAdvanced = true; isAdvanced = true;
side._isCheckedEdge[ iE ] = true; side._isCheckedEdge[ iE ] = true;
@ -2811,7 +2839,7 @@ bool StdMeshers_Prism_3D::IsApplicable(const TopoDS_Shape & shape, bool toCheckA
const TopoDS_Shape& topFace = sides[0]._faces->FindKey( nbFaces ); const TopoDS_Shape& topFace = sides[0]._faces->FindKey( nbFaces );
size_t iS; size_t iS;
for ( iS = 1; iS < sides.size(); ++iS ) for ( iS = 1; iS < sides.size(); ++iS )
if ( !sides[ iS ]._faces->Contains( topFace )) if ( ! sides[ iS ]._faces->Contains( topFace ))
break; break;
prismDetected = ( iS == sides.size() ); prismDetected = ( iS == sides.size() );
} }
@ -3285,7 +3313,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
if ( nbUnitePerEdge[ iE ] < 0 ) if ( nbUnitePerEdge[ iE ] < 0 )
continue; continue;
// look for already united faces // look for already united faces
for ( int i = iE; i < iE + nbExraFaces; ++i ) for ( size_t i = iE; i < iE + nbExraFaces; ++i )
{ {
if ( nbUnitePerEdge[ i ] > 0 ) // a side including nbUnitePerEdge[i]+1 edge if ( nbUnitePerEdge[ i ] > 0 ) // a side including nbUnitePerEdge[i]+1 edge
nbExraFaces += nbUnitePerEdge[ i ]; nbExraFaces += nbUnitePerEdge[ i ];
@ -3324,7 +3352,7 @@ bool StdMeshers_PrismAsBlock::Init(SMESH_MesherHelper* helper,
else if ( nbExraFaces > 1 ) // unite else if ( nbExraFaces > 1 ) // unite
{ {
double u0 = 0, sumLen = 0; double u0 = 0, sumLen = 0;
for ( int i = iE; i < iE + nbExraFaces; ++i ) for ( size_t i = iE; i < iE + nbExraFaces; ++i )
sumLen += edgeLength[ i ]; sumLen += edgeLength[ i ];
vector< TSideFace* > components( nbExraFaces ); vector< TSideFace* > components( nbExraFaces );
@ -3568,7 +3596,7 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> &
double tol2; double tol2;
{ {
Bnd_B3d bndBox; Bnd_B3d bndBox;
for ( int i = 0; i < columns.size(); ++i ) for ( size_t i = 0; i < columns.size(); ++i )
bndBox.Add( gpXYZ( columns[i]->front() )); bndBox.Add( gpXYZ( columns[i]->front() ));
tol2 = bndBox.SquareExtent() * 1e-5; tol2 = bndBox.SquareExtent() * 1e-5;
} }
@ -3591,7 +3619,7 @@ bool StdMeshers_PrismAsBlock::GetLayersTransformation(vector<gp_Trsf> &
//t.SetScaleFactor( distZ/dist0 ); - it does not work properly, wrong base point //t.SetScaleFactor( distZ/dist0 ); - it does not work properly, wrong base point
// check a transformation // check a transformation
for ( int i = 0; i < columns.size(); ++i ) for ( size_t i = 0; i < columns.size(); ++i )
{ {
gp_Pnt p0 = gpXYZ( (*columns[i])[0] ); gp_Pnt p0 = gpXYZ( (*columns[i])[0] );
gp_Pnt pz = gpXYZ( (*columns[i])[z] ); gp_Pnt pz = gpXYZ( (*columns[i])[z] );
@ -3795,7 +3823,7 @@ StdMeshers_PrismAsBlock::TSideFace::TSideFace( const TSideFace& other ):
myComponents ( other.myComponents.size() ), myComponents ( other.myComponents.size() ),
myHelper ( *other.myHelper.GetMesh() ) myHelper ( *other.myHelper.GetMesh() )
{ {
for (int i = 0 ; i < myComponents.size(); ++i ) for ( size_t i = 0 ; i < myComponents.size(); ++i )
myComponents[ i ] = new TSideFace( *other.myComponents[ i ]); myComponents[ i ] = new TSideFace( *other.myComponents[ i ]);
} }
@ -3807,7 +3835,7 @@ StdMeshers_PrismAsBlock::TSideFace::TSideFace( const TSideFace& other ):
StdMeshers_PrismAsBlock::TSideFace::~TSideFace() StdMeshers_PrismAsBlock::TSideFace::~TSideFace()
{ {
for (int i = 0 ; i < myComponents.size(); ++i ) for ( size_t i = 0 ; i < myComponents.size(); ++i )
if ( myComponents[ i ] ) if ( myComponents[ i ] )
delete myComponents[ i ]; delete myComponents[ i ];
} }
@ -3907,7 +3935,7 @@ StdMeshers_PrismAsBlock::TSideFace::GetComponent(const double U,double & localU)
if ( myComponents.empty() ) if ( myComponents.empty() )
return const_cast<TSideFace*>( this ); return const_cast<TSideFace*>( this );
int i; size_t i;
for ( i = 0; i < myComponents.size(); ++i ) for ( i = 0; i < myComponents.size(); ++i )
if ( U < myParams[ i ].second ) if ( U < myParams[ i ].second )
break; break;
@ -4346,9 +4374,9 @@ gp_Pnt StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::Value(const Standard_Real
void StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::dumpNodes(int nbNodes) const void StdMeshers_PrismAsBlock::TVerticalEdgeAdaptor::dumpNodes(int nbNodes) const
{ {
#ifdef _DEBUG_ #ifdef _DEBUG_
for ( int i = 0; i < nbNodes && i < myNodeColumn->size(); ++i ) for ( int i = 0; i < nbNodes && i < (int)myNodeColumn->size(); ++i )
cout << (*myNodeColumn)[i]->GetID() << " "; cout << (*myNodeColumn)[i]->GetID() << " ";
if ( nbNodes < myNodeColumn->size() ) if ( nbNodes < (int) myNodeColumn->size() )
cout << myNodeColumn->back()->GetID(); cout << myNodeColumn->back()->GetID();
#endif #endif
} }

View File

@ -24,6 +24,7 @@
#include "StdMeshers_QuadToTriaAdaptor.hxx" #include "StdMeshers_QuadToTriaAdaptor.hxx"
#include "SMDS_IteratorOnIterators.hxx"
#include "SMDS_SetIterator.hxx" #include "SMDS_SetIterator.hxx"
#include "SMESHDS_GroupBase.hxx" #include "SMESHDS_GroupBase.hxx"
#include "SMESH_Algo.hxx" #include "SMESH_Algo.hxx"
@ -115,20 +116,20 @@ namespace
gp_Vec nJ = baseVec.Crossed( baJ ); gp_Vec nJ = baseVec.Crossed( baJ );
// Check angle between normals // Check angle between normals
double angle = nI.Angle( nJ ); double angle = nI.Angle( nJ );
bool tooClose = ( angle < 15. * M_PI / 180. ); bool tooClose = ( angle < 15. * M_PI / 180. );
// Check if pyramids collide // Check if pyramids collide
if ( !tooClose && ( baI * baJ > 0 ) && ( nI * nJ > 0 )) if ( !tooClose && ( baI * baJ > 0 ) && ( nI * nJ > 0 ))
{ {
// find out if nI points outside of PrmI or inside // find out if nI points outside of PrmI or inside
int dInd = baseNodesIndI[1] - baseNodesIndI[0]; int dInd = baseNodesIndI[1] - baseNodesIndI[0];
bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0; bool isOutI = ( abs(dInd)==1 ) ? dInd < 0 : dInd > 0;
// find out sign of projection of nJ to baI // find out sign of projection of baI to nJ
double proj = baI * nJ; double proj = baI * nJ;
tooClose = isOutI ? proj > 0 : proj < 0; tooClose = ( isOutI ? proj > 0 : proj < 0 );
} }
// Check if PrmI and PrmJ are in same domain // Check if PrmI and PrmJ are in same domain
@ -170,8 +171,9 @@ namespace
continue; // f is a base quadrangle continue; // f is a base quadrangle
// check projections of face direction (baOFN) to triange normals (nI and nJ) // check projections of face direction (baOFN) to triange normals (nI and nJ)
gp_Vec baOFN( base1, SMESH_TNodeXYZ( otherFaceNode )); gp_Vec baOFN( base2, SMESH_TNodeXYZ( otherFaceNode ));
if ( nI * baOFN > 0 && nJ * baOFN > 0 ) if ( nI * baOFN > 0 && nJ * baOFN > 0 &&
baI* baOFN > 0 && baJ* baOFN > 0 ) // issue 0023212
{ {
tooClose = false; // f is between pyramids tooClose = false; // f is between pyramids
break; break;
@ -253,7 +255,6 @@ namespace
} }
} }
} }
} }
//================================================================================ //================================================================================
@ -266,6 +267,8 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement* Pr
const SMDS_MeshElement* PrmJ, const SMDS_MeshElement* PrmJ,
set<const SMDS_MeshNode*> & nodesToMove) set<const SMDS_MeshNode*> & nodesToMove)
{ {
// cout << endl << "Merge " << PrmI->GetID() << " " << PrmJ->GetID() << " "
// << PrmI->GetNode(4) << PrmJ->GetNode(4) << endl;
const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove const SMDS_MeshNode* Nrem = PrmJ->GetNode(4); // node to remove
//int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume ); //int nbJ = Nrem->NbInverseElements( SMDSAbs_Volume );
SMESH_TNodeXYZ Pj( Nrem ); SMESH_TNodeXYZ Pj( Nrem );
@ -288,7 +291,7 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement* Pr
vector< const SMDS_MeshElement* > inverseElems 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); ( TStdElemIterator( CommonNode->GetInverseElementIterator(SMDSAbs_Face)), itEnd);
for ( unsigned i = 0; i < inverseElems.size(); ++i ) for ( size_t i = 0; i < inverseElems.size(); ++i )
{ {
const SMDS_MeshElement* FI = inverseElems[i]; const SMDS_MeshElement* FI = inverseElems[i];
const SMDS_MeshElement* FJEqual = 0; const SMDS_MeshElement* FJEqual = 0;
@ -309,11 +312,12 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement* Pr
} }
// set the common apex node to pyramids and triangles merged with J // set the common apex node to pyramids and triangles merged with J
vector< const SMDS_MeshNode* > nodes;
inverseElems.assign( TStdElemIterator( Nrem->GetInverseElementIterator()), itEnd ); inverseElems.assign( TStdElemIterator( Nrem->GetInverseElementIterator()), itEnd );
for ( unsigned i = 0; i < inverseElems.size(); ++i ) for ( size_t i = 0; i < inverseElems.size(); ++i )
{ {
const SMDS_MeshElement* elem = inverseElems[i]; const SMDS_MeshElement* elem = inverseElems[i];
vector< const SMDS_MeshNode* > nodes( elem->begin_nodes(), elem->end_nodes() ); nodes.assign( elem->begin_nodes(), elem->end_nodes() );
nodes[ elem->GetType() == SMDSAbs_Volume ? PYRAM_APEX : TRIA_APEX ] = CommonNode; nodes[ elem->GetType() == SMDSAbs_Volume ? PYRAM_APEX : TRIA_APEX ] = CommonNode;
GetMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size()); GetMeshDS()->ChangeElementNodes( elem, &nodes[0], nodes.size());
} }
@ -330,33 +334,34 @@ void StdMeshers_QuadToTriaAdaptor::MergePiramids( const SMDS_MeshElement* Pr
//================================================================================ //================================================================================
void StdMeshers_QuadToTriaAdaptor::MergeAdjacent(const SMDS_MeshElement* PrmI, void StdMeshers_QuadToTriaAdaptor::MergeAdjacent(const SMDS_MeshElement* PrmI,
set<const SMDS_MeshNode*>& nodesToMove) set<const SMDS_MeshNode*>& nodesToMove,
const bool isRecursion)
{ {
TIDSortedElemSet adjacentPyrams; TIDSortedElemSet adjacentPyrams;
bool mergedPyrams = false; bool mergedPyrams = false;
for(int k=0; k<4; k++) // loop on 4 base nodes of PrmI for ( int k=0; k<4; k++ ) // loop on 4 base nodes of PrmI
{ {
const SMDS_MeshNode* n = PrmI->GetNode(k); const SMDS_MeshNode* n = PrmI->GetNode(k);
SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); SMDS_ElemIteratorPtr vIt = n->GetInverseElementIterator( SMDSAbs_Volume );
while ( vIt->more() ) while ( vIt->more() )
{ {
const SMDS_MeshElement* PrmJ = vIt->next(); const SMDS_MeshElement* PrmJ = vIt->next();
if ( PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second ) if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 || !adjacentPyrams.insert( PrmJ ).second )
continue; continue;
if ( PrmI != PrmJ && TooCloseAdjacent( PrmI, PrmJ, GetMesh()->HasShapeToMesh() )) if ( TooCloseAdjacent( PrmI, PrmJ, GetMesh()->HasShapeToMesh() ))
{ {
MergePiramids( PrmI, PrmJ, nodesToMove ); MergePiramids( PrmI, PrmJ, nodesToMove );
mergedPyrams = true; mergedPyrams = true;
// container of inverse elements can change // container of inverse elements can change
vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); // vIt = n->GetInverseElementIterator( SMDSAbs_Volume ); -- iterator re-implemented
} }
} }
} }
if ( mergedPyrams ) if ( mergedPyrams && !isRecursion )
{ {
TIDSortedElemSet::iterator prm; TIDSortedElemSet::iterator prm;
for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm) for (prm = adjacentPyrams.begin(); prm != adjacentPyrams.end(); ++prm)
MergeAdjacent( *prm, nodesToMove ); MergeAdjacent( *prm, nodesToMove, true );
} }
} }
@ -414,79 +419,58 @@ static gp_Pnt FindBestPoint(const gp_Pnt& P1, const gp_Pnt& P2,
//======================================================================= //=======================================================================
//function : HasIntersection3 //function : HasIntersection3
//purpose : Auxilare for HasIntersection() //purpose : Find intersection point between a triangle (P1,P2,P3)
// find intersection point between triangle (P1,P2,P3) // and a segment [PC,P]
// and segment [PC,P]
//======================================================================= //=======================================================================
static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint, static bool HasIntersection3(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3)
{ {
//cout<<"HasIntersection3"<<endl; const double EPSILON = 1e-6;
//cout<<" PC("<<PC.X()<<","<<PC.Y()<<","<<PC.Z()<<")"<<endl; double segLen = P.Distance( PC );
//cout<<" P("<<P.X()<<","<<P.Y()<<","<<P.Z()<<")"<<endl;
//cout<<" P1("<<P1.X()<<","<<P1.Y()<<","<<P1.Z()<<")"<<endl;
//cout<<" P2("<<P2.X()<<","<<P2.Y()<<","<<P2.Z()<<")"<<endl;
//cout<<" P3("<<P3.X()<<","<<P3.Y()<<","<<P3.Z()<<")"<<endl;
gp_Vec VP1(P1,P2);
gp_Vec VP2(P1,P3);
IntAna_Quadric IAQ(gp_Pln(P1,VP1.Crossed(VP2)));
IntAna_IntConicQuad IAICQ(gp_Lin(PC,gp_Dir(gp_Vec(PC,P))),IAQ);
if(IAICQ.IsDone()) {
if( IAICQ.IsInQuadric() )
return false;
if( IAICQ.NbPoints() == 1 ) {
gp_Pnt PIn = IAICQ.Point(1);
const double preci = 1.e-10 * P.Distance(PC);
// check if this point is internal for segment [PC,P]
bool IsExternal =
( (PC.X()-PIn.X())*(P.X()-PIn.X()) > preci ) ||
( (PC.Y()-PIn.Y())*(P.Y()-PIn.Y()) > preci ) ||
( (PC.Z()-PIn.Z())*(P.Z()-PIn.Z()) > preci );
if(IsExternal) {
return false;
}
// check if this point is internal for triangle (P1,P2,P3)
gp_Vec V1(PIn,P1);
gp_Vec V2(PIn,P2);
gp_Vec V3(PIn,P3);
if( V1.Magnitude()<preci ||
V2.Magnitude()<preci ||
V3.Magnitude()<preci ) {
Pint = PIn;
return true;
}
const double angularTol = 1e-6;
gp_Vec VC1 = V1.Crossed(V2);
gp_Vec VC2 = V2.Crossed(V3);
gp_Vec VC3 = V3.Crossed(V1);
if(VC1.Magnitude()<gp::Resolution()) {
if(VC2.IsOpposite(VC3,angularTol)) {
return false;
}
}
else if(VC2.Magnitude()<gp::Resolution()) {
if(VC1.IsOpposite(VC3,angularTol)) {
return false;
}
}
else if(VC3.Magnitude()<gp::Resolution()) {
if(VC1.IsOpposite(VC2,angularTol)) {
return false;
}
}
else {
if( VC1.IsOpposite(VC2,angularTol) || VC1.IsOpposite(VC3,angularTol) ||
VC2.IsOpposite(VC3,angularTol) ) {
return false;
}
}
Pint = PIn;
return true;
}
}
return false; gp_XYZ orig = PC.XYZ();
gp_XYZ dir = ( P.XYZ() - PC.XYZ() ) / segLen;
gp_XYZ vert0 = P1.XYZ();
gp_XYZ vert1 = P2.XYZ();
gp_XYZ vert2 = P3.XYZ();
/* calculate distance from vert0 to ray origin */
gp_XYZ tvec = orig - vert0;
gp_XYZ edge1 = vert1 - vert0;
gp_XYZ edge2 = vert2 - vert0;
/* begin calculating determinant - also used to calculate U parameter */
gp_XYZ pvec = dir ^ edge2;
/* if determinant is near zero, ray lies in plane of triangle */
double det = edge1 * pvec;
if (det > -EPSILON && det < EPSILON)
return false;
/* calculate U parameter and test bounds */
double u = ( tvec * pvec ) / det;
//if (u < 0.0 || u > 1.0)
if (u < -EPSILON || u > 1.0 + EPSILON)
return false;
/* prepare to test V parameter */
gp_XYZ qvec = tvec ^ edge1;
/* calculate V parameter and test bounds */
double v = (dir * qvec) / det;
//if ( v < 0.0 || u + v > 1.0 )
if ( v < -EPSILON || u + v > 1.0 + EPSILON)
return false;
/* calculate t, ray intersects triangle */
double t = (edge2 * qvec) / det;
Pint = orig + dir * t;
return ( t > 0. && t < segLen );
} }
//======================================================================= //=======================================================================
@ -521,54 +505,99 @@ static bool HasIntersection(const gp_Pnt& P, const gp_Pnt& PC, gp_Pnt& Pint,
//================================================================================ //================================================================================
/*! /*!
* \brief Checks if a line segment (P,PC) intersects any mesh face. * \brief Return allowed height of a pyramid
* \param P - first segment end * \param Papex - optimal pyramid apex
* \param PC - second segment end (it is a gravity center of quadrangle) * \param PC - gravity center of a quadrangle
* \param Pint - (out) intersection point * \param PN - four nodes of the quadrangle
* \param aMesh - mesh * \param aMesh - mesh
* \param aShape - shape to check faces on * \param NotCheckedFace - the quadrangle face
* \param NotCheckedFace - mesh face not to check * \retval double - pyramid height
* \retval bool - true if there is an intersection
*/ */
//================================================================================ //================================================================================
bool StdMeshers_QuadToTriaAdaptor::CheckIntersection (const gp_Pnt& P, void StdMeshers_QuadToTriaAdaptor::LimitHeight (gp_Pnt& Papex,
const gp_Pnt& PC, const gp_Pnt& PC,
gp_Pnt& Pint, const TColgp_Array1OfPnt& PN,
SMESH_Mesh& aMesh, const vector<const SMDS_MeshNode*>& FNodes,
const TopoDS_Shape& aShape, SMESH_Mesh& aMesh,
const SMDS_MeshElement* NotCheckedFace) const SMDS_MeshElement* NotCheckedFace,
const bool UseApexRay)
{ {
if ( !myElemSearcher ) if ( !myElemSearcher )
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *aMesh.GetMeshDS() ); myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *aMesh.GetMeshDS() );
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher); SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher);
bool res = false; // Find intersection of faces with (P,PC) segment elongated 3 times
double dist = RealLast(); // find intersection closest to PC
gp_Pnt Pres;
gp_Ax1 line( P, gp_Vec(P,PC));
vector< const SMDS_MeshElement* > suspectElems;
searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems);
double height = Papex.Distance( PC );
gp_Ax1 line( PC, gp_Vec( PC, Papex ));
gp_Pnt Pint, Ptest;
vector< const SMDS_MeshElement* > suspectFaces;
TColgp_SequenceOfPnt aContour; TColgp_SequenceOfPnt aContour;
for ( size_t iF = 0; iF < suspectElems.size(); ++iF )
if ( UseApexRay )
{ {
const SMDS_MeshElement* face = suspectElems[iF]; // find intersection closest to PC
if ( face == NotCheckedFace ) continue; Ptest = PC.XYZ() + line.Direction().XYZ() * height * 3;
aContour.Clear();
for ( int i = 0; i < face->NbCornerNodes(); ++i ) searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectFaces );
aContour.Append( SMESH_TNodeXYZ( face->GetNode(i) )); for ( size_t iF = 0; iF < suspectFaces.size(); ++iF )
if ( HasIntersection(P, PC, Pres, aContour)) { {
res = true; const SMDS_MeshElement* face = suspectFaces[iF];
double tmp = PC.Distance(Pres); if ( face == NotCheckedFace ) continue;
if ( tmp < dist ) {
Pint = Pres; aContour.Clear();
dist = tmp; for ( int i = 0, nb = face->NbCornerNodes(); i < nb; ++i )
aContour.Append( SMESH_TNodeXYZ( face->GetNode(i) ));
if ( HasIntersection( Ptest, PC, Pint, aContour ))
{
double dInt = PC.Distance( Pint );
height = Min( height, dInt / 3. );
} }
} }
} }
return res;
// Find faces intersecting triangular facets of the pyramid (issue 23212)
gp_XYZ center = PC.XYZ() + line.Direction().XYZ() * height * 0.5;
double diameter = Max( PN(1).Distance(PN(3)), PN(2).Distance(PN(4)));
suspectFaces.clear();
searcher->GetElementsInSphere( center, diameter * 0.6, SMDSAbs_Face, suspectFaces);
const double upShift = 1.5;
Ptest = PC.XYZ() + line.Direction().XYZ() * height * upShift; // tmp apex
for ( size_t iF = 0; iF < suspectFaces.size(); ++iF )
{
const SMDS_MeshElement* face = suspectFaces[iF];
if ( face == NotCheckedFace ) continue;
if ( face->GetNodeIndex( FNodes[0] ) >= 0 ||
face->GetNodeIndex( FNodes[1] ) >= 0 ||
face->GetNodeIndex( FNodes[2] ) >= 0 ||
face->GetNodeIndex( FNodes[3] ) >= 0 )
continue; // neighbor face of the quadrangle
// limit height using points of intersection of face links with pyramid facets
int nbN = face->NbCornerNodes();
gp_Pnt P1 = SMESH_TNodeXYZ( face->GetNode( nbN-1 )); // 1st link end
for ( int i = 0; i < nbN; ++i )
{
gp_Pnt P2 = SMESH_TNodeXYZ( face->GetNode(i) ); // 2nd link end
for ( int iN = 1; iN <= 4; ++iN ) // loop on pyramid facets
{
if ( HasIntersection3( P1, P2, Pint, PN(iN), PN(iN+1), Ptest ))
{
height = Min( height, gp_Vec( PC, Pint ) * line.Direction() );
//Ptest = PC.XYZ() + line.Direction().XYZ() * height * upShift; // new tmp apex
}
}
P1 = P2;
}
}
Papex = PC.XYZ() + line.Direction().XYZ() * height;
} }
//================================================================================ //================================================================================
@ -720,25 +749,36 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh,
vector<const SMDS_MeshElement*> myPyramids; vector<const SMDS_MeshElement*> myPyramids;
const SMESHDS_SubMesh * aSubMeshDSFace;
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
SMESH_MesherHelper helper(aMesh); SMESH_MesherHelper helper(aMesh);
helper.IsQuadraticSubMesh(aShape); helper.IsQuadraticSubMesh(aShape);
helper.SetElementsOnShape( true ); helper.SetElementsOnShape( true );
if ( myElemSearcher ) delete myElemSearcher; if ( myElemSearcher ) delete myElemSearcher;
vector< SMDS_ElemIteratorPtr > itVec;
if ( aProxyMesh ) if ( aProxyMesh )
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS, aProxyMesh->GetFaces(aShape)); {
itVec.push_back( aProxyMesh->GetFaces( aShape ));
}
else else
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS ); {
for ( TopExp_Explorer exp(aShape,TopAbs_FACE); exp.More(); exp.Next() )
if (( aSubMeshDSFace = aProxyMesh->GetSubMesh( exp.Current() )))
itVec.push_back( aSubMeshDSFace->GetElements() );
}
typedef
SMDS_IteratorOnIterators< const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > > TIter;
SMDS_ElemIteratorPtr faceIt( new TIter( itVec ));
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS, faceIt );
const SMESHDS_SubMesh * aSubMeshDSFace;
TColgp_Array1OfPnt PN(1,5); TColgp_Array1OfPnt PN(1,5);
TColgp_Array1OfVec VN(1,4); TColgp_Array1OfVec VN(1,4);
vector<const SMDS_MeshNode*> FNodes(5); vector<const SMDS_MeshNode*> FNodes(5);
gp_Pnt PC; gp_Pnt PC;
gp_Vec VNorm; gp_Vec VNorm;
for (TopExp_Explorer exp(aShape,TopAbs_FACE);exp.More();exp.Next()) for ( TopExp_Explorer exp(aShape,TopAbs_FACE); exp.More(); exp.Next() )
{ {
const TopoDS_Shape& aShapeFace = exp.Current(); const TopoDS_Shape& aShapeFace = exp.Current();
if ( aProxyMesh ) if ( aProxyMesh )
@ -809,17 +849,7 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh,
} }
else { else {
// check possible intersection with other faces // check possible intersection with other faces
gp_Pnt Pint; LimitHeight( PCbest, PC, PN, FNodes, aMesh, face, /*UseApexRay=*/true );
gp_Vec VB(PC,PCbest);
gp_Pnt PCbestTmp = PC.XYZ() + VB.XYZ() * 3.0;
bool hasInters = CheckIntersection(PCbestTmp, PC, Pint, aMesh, aShape, face);
if ( hasInters ) {
double dist = PC.Distance(Pint)/3.;
if ( dist < height ) {
gp_Dir aDir( VB );
PCbest = PC.XYZ() + aDir.XYZ() * dist;
}
}
} }
// create node for PCbest // create node for PCbest
SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() ); SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
@ -971,11 +1001,11 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
gp_Pnt Pres1,Pres2; gp_Pnt Pres1,Pres2;
gp_Ax1 line( PC, VNorm ); gp_Ax1 line( PC, VNorm );
vector< const SMDS_MeshElement* > suspectElems; vector< const SMDS_MeshElement* > suspectFaces;
searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectFaces);
for ( size_t iF = 0; iF < suspectElems.size(); ++iF ) { for ( size_t iF = 0; iF < suspectFaces.size(); ++iF ) {
const SMDS_MeshElement* F = suspectElems[iF]; const SMDS_MeshElement* F = suspectFaces[iF];
if ( F == face ) continue; if ( F == face ) continue;
aContour.Clear(); aContour.Clear();
for ( int i = 0; i < 4; ++i ) for ( int i = 0; i < 4; ++i )
@ -1026,7 +1056,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
continue; continue;
} }
// -----------------------------------
// Case of non-degenerated quadrangle // Case of non-degenerated quadrangle
// -----------------------------------
// Find pyramid peak // Find pyramid peak
@ -1059,12 +1091,12 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
gp_Pnt intPnt[2]; gp_Pnt intPnt[2];
gp_Ax1 line( PC, tmpDir ); gp_Ax1 line( PC, tmpDir );
vector< const SMDS_MeshElement* > suspectElems; vector< const SMDS_MeshElement* > suspectFaces;
searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectElems); searcher->GetElementsNearLine( line, SMDSAbs_Face, suspectFaces);
for ( size_t iF = 0; iF < suspectElems.size(); ++iF ) for ( size_t iF = 0; iF < suspectFaces.size(); ++iF )
{ {
const SMDS_MeshElement* F = suspectElems[iF]; const SMDS_MeshElement* F = suspectFaces[iF];
if ( F == face ) continue; if ( F == face ) continue;
aContour.Clear(); aContour.Clear();
int nbN = F->NbCornerNodes(); int nbN = F->NbCornerNodes();
@ -1109,13 +1141,15 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
{ {
if( !intersected[isRev] ) continue; if( !intersected[isRev] ) continue;
double pyramidH = Min( height, PC.Distance(intPnt[isRev])/3.); double pyramidH = Min( height, PC.Distance(intPnt[isRev])/3.);
PCbest = PC.XYZ() + tmpDir.XYZ() * (isRev ? -pyramidH : pyramidH); gp_Pnt Papex = PC.XYZ() + tmpDir.XYZ() * (isRev ? -pyramidH : pyramidH);
// create node for PCbest LimitHeight( Papex, PC, PN, FNodes, aMesh, face, /*UseApexRay=*/false );
SMDS_MeshNode* NewNode = helper.AddNode( PCbest.X(), PCbest.Y(), PCbest.Z() );
// create node for Papex
SMDS_MeshNode* NewNode = helper.AddNode( Papex.X(), Papex.Y(), Papex.Z() );
// add triangles to result map // add triangles to result map
for(i=0; i<4; i++) { for ( i = 0; i < 4; i++) {
SMDS_MeshFace* NewFace; SMDS_MeshFace* NewFace;
if(isRev) if(isRev)
NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] ); NewFace = meshDS->AddFace( NewNode, FNodes[i], FNodes[i+1] );
@ -1146,16 +1180,19 @@ bool StdMeshers_QuadToTriaAdaptor::Compute(SMESH_Mesh& aMesh)
bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh, bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh& aMesh,
const vector<const SMDS_MeshElement*>& myPyramids) const vector<const SMDS_MeshElement*>& myPyramids)
{ {
if(myPyramids.empty()) if ( myPyramids.empty() )
return true; return true;
SMESHDS_Mesh * meshDS = aMesh.GetMeshDS(); SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
size_t i, j, k; size_t i, j, k;
int myShapeID = myPyramids[0]->GetNode(4)->getshapeId(); //int myShapeID = myPyramids[0]->GetNode(4)->getshapeId();
{
if ( myElemSearcher ) delete myElemSearcher; SMDS_ElemIteratorPtr
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS ); pyramIt( new SMDS_ElementVectorIterator( myPyramids.begin(), myPyramids.end() ));
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>(myElemSearcher); if ( myElemSearcher ) delete myElemSearcher;
myElemSearcher = SMESH_MeshAlgos::GetElementSearcher( *meshDS, pyramIt );
}
SMESH_ElementSearcher* searcher = const_cast<SMESH_ElementSearcher*>( myElemSearcher );
set<const SMDS_MeshNode*> nodesToMove; set<const SMDS_MeshNode*> nodesToMove;
@ -1167,17 +1204,19 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
MergeAdjacent( PrmI, nodesToMove ); MergeAdjacent( PrmI, nodesToMove );
} }
// iterate on all pyramids // iterate on all new pyramids
vector< const SMDS_MeshElement* > suspectPyrams;
for ( i = 0; i < myPyramids.size(); ++i ) for ( i = 0; i < myPyramids.size(); ++i )
{ {
const SMDS_MeshElement* PrmI = myPyramids[i]; const SMDS_MeshElement* PrmI = myPyramids[i];
const SMDS_MeshNode* apexI = PrmI->GetNode( PYRAM_APEX );
// compare PrmI with all the rest pyramids // compare PrmI with all the rest pyramids
// collect adjacent pyramids and nodes coordinates of PrmI // collect adjacent pyramids and nodes coordinates of PrmI
set<const SMDS_MeshElement*> checkedPyrams; set<const SMDS_MeshElement*> checkedPyrams;
vector<gp_Pnt> PsI(5); gp_Pnt PsI[5];
for(k=0; k<5; k++) // loop on 4 base nodes of PrmI for ( k = 0; k < 5; k++ )
{ {
const SMDS_MeshNode* n = PrmI->GetNode(k); const SMDS_MeshNode* n = PrmI->GetNode(k);
PsI[k] = SMESH_TNodeXYZ( n ); PsI[k] = SMESH_TNodeXYZ( n );
@ -1190,70 +1229,77 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
} }
} }
// get pyramids to check
gp_XYZ PC = ( PsI[0].XYZ() + PsI[1].XYZ() + PsI[2].XYZ() + PsI[3].XYZ() ) / 4.;
gp_XYZ ray = PsI[4].XYZ() - PC;
gp_XYZ center = PC + 0.5 * ray;
double diameter = Max( PsI[0].Distance(PsI[2]), PsI[1].Distance(PsI[3]));
suspectPyrams.clear();
searcher->GetElementsInSphere( center, diameter * 0.6, SMDSAbs_Volume, suspectPyrams);
// check intersection with distant pyramids // check intersection with distant pyramids
for(k=0; k<4; k++) // loop on 4 base nodes of PrmI for ( j = 0; j < suspectPyrams.size(); ++j )
{ {
gp_Vec Vtmp(PsI[k],PsI[4]); const SMDS_MeshElement* PrmJ = suspectPyrams[j];
gp_Ax1 line( PsI[k], Vtmp ); if ( PrmJ == PrmI )
vector< const SMDS_MeshElement* > suspectPyrams; continue;
searcher->GetElementsNearLine( line, SMDSAbs_Volume, suspectPyrams); if ( apexI == PrmJ->GetNode( PYRAM_APEX ))
continue; // pyramids PrmI and PrmJ already merged
if ( !checkedPyrams.insert( PrmJ ).second )
continue; // already checked
for ( j = 0; j < suspectPyrams.size(); ++j ) gp_Pnt PsJ[5];
for ( k = 0; k < 5; k++ )
PsJ[k] = SMESH_TNodeXYZ( PrmJ->GetNode(k) );
if ( ray * ( PsJ[4].XYZ() - PC ) < 0. )
continue; // PrmJ is below PrmI
for ( k = 0; k < 4; k++ ) // loop on 4 base nodes of PrmI
{ {
const SMDS_MeshElement* PrmJ = suspectPyrams[j];
if ( PrmJ == PrmI || PrmJ->NbCornerNodes() != 5 )
continue;
if ( myShapeID != PrmJ->GetNode(4)->getshapeId())
continue; // pyramid from other SOLID
if ( PrmI->GetNode(4) == PrmJ->GetNode(4) )
continue; // pyramids PrmI and PrmJ already merged
if ( !checkedPyrams.insert( PrmJ ).second )
continue; // already checked
TXyzIterator xyzIt( PrmJ->nodesIterator() );
vector<gp_Pnt> PsJ( xyzIt, TXyzIterator() );
gp_Pnt Pint; gp_Pnt Pint;
bool hasInt=false; bool hasInt=false;
for(k=0; k<4 && !hasInt; k++) { for ( k = 0; k < 4 && !hasInt; k++ )
gp_Vec Vtmp(PsI[k],PsI[4]); {
gp_Vec Vtmp( PsI[k], PsI[ PYRAM_APEX ]);
gp_Pnt Pshift = PsI[k].XYZ() + Vtmp.XYZ() * 0.01; // base node moved a bit to apex 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[0], PsJ[1], PsJ[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[4]) || HasIntersection3( Pshift, PsI[4], Pint, PsJ[1], PsJ[2], PsJ[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[4]) || HasIntersection3( Pshift, PsI[4], Pint, PsJ[2], PsJ[3], PsJ[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsI[4], Pint, PsJ[3], PsJ[0], PsJ[4]) ); HasIntersection3( Pshift, PsI[4], Pint, PsJ[3], PsJ[0], PsJ[PYRAM_APEX]) );
} }
for(k=0; k<4 && !hasInt; k++) { for ( k = 0; k < 4 && !hasInt; k++ )
gp_Vec Vtmp(PsJ[k],PsJ[4]); {
gp_Vec Vtmp( PsJ[k], PsJ[ PYRAM_APEX ]);
gp_Pnt Pshift = PsJ[k].XYZ() + Vtmp.XYZ() * 0.01; 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[0], PsI[1], PsI[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[4]) || HasIntersection3( Pshift, PsJ[4], Pint, PsI[1], PsI[2], PsI[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[4]) || HasIntersection3( Pshift, PsJ[4], Pint, PsI[2], PsI[3], PsI[PYRAM_APEX]) ||
HasIntersection3( Pshift, PsJ[4], Pint, PsI[3], PsI[0], PsI[4]) ); HasIntersection3( Pshift, PsJ[4], Pint, PsI[3], PsI[0], PsI[PYRAM_APEX]) );
} }
if ( hasInt ) if ( hasInt )
{ {
// count common nodes of base faces of two pyramids // count common nodes of base faces of two pyramids
int nbc = 0; int nbc = 0;
for (k=0; k<4; k++) for ( k = 0; k < 4; k++ )
nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 ); nbc += int ( PrmI->GetNodeIndex( PrmJ->GetNode(k) ) >= 0 );
if ( nbc == 4 ) if ( nbc == 4 )
continue; // pyrams have a common base face continue; // pyrams have a common base face
if(nbc>0) if ( nbc > 0 )
{ {
// Merge the two pyramids and others already merged with them // Merge the two pyramids and others already merged with them
MergePiramids( PrmI, PrmJ, nodesToMove ); MergePiramids( PrmI, PrmJ, nodesToMove );
} }
else { // nbc==0 else // nbc==0
{
// decrease height of pyramids // decrease height of pyramids
gp_XYZ PCi(0,0,0), PCj(0,0,0); gp_XYZ PCi(0,0,0), PCj(0,0,0);
for(k=0; k<4; k++) { for ( k = 0; k < 4; k++ ) {
PCi += PsI[k].XYZ(); PCi += PsI[k].XYZ();
PCj += PsJ[k].XYZ(); PCj += PsJ[k].XYZ();
} }
@ -1272,9 +1318,9 @@ bool StdMeshers_QuadToTriaAdaptor::Compute2ndPart(SMESH_Mesh&
VN1.Scale(coef1); VN1.Scale(coef1);
VN2.Scale(coef2); VN2.Scale(coef2);
SMDS_MeshNode* aNode1 = const_cast<SMDS_MeshNode*>(PrmI->GetNode(4)); SMDS_MeshNode* aNode1 = const_cast<SMDS_MeshNode*>( apexI );
aNode1->setXYZ( PCi.X()+VN1.X(), PCi.Y()+VN1.Y(), PCi.Z()+VN1.Z() ); aNode1->setXYZ( PCi.X()+VN1.X(), PCi.Y()+VN1.Y(), PCi.Z()+VN1.Z() );
SMDS_MeshNode* aNode2 = const_cast<SMDS_MeshNode*>(PrmJ->GetNode(4)); SMDS_MeshNode* aNode2 = const_cast<SMDS_MeshNode*>(PrmJ->GetNode( PYRAM_APEX ));
aNode2->setXYZ( PCj.X()+VN2.X(), PCj.Y()+VN2.Y(), PCj.Z()+VN2.Z() ); aNode2->setXYZ( PCj.X()+VN2.X(), PCj.Y()+VN2.Y(), PCj.Z()+VN2.Z() );
nodesToMove.insert( aNode1 ); nodesToMove.insert( aNode1 );
nodesToMove.insert( aNode2 ); nodesToMove.insert( aNode2 );

View File

@ -71,10 +71,13 @@ protected:
gp_Pnt& PC, gp_Vec& VNorm, gp_Pnt& PC, gp_Vec& VNorm,
const SMDS_MeshElement** volumes=0); const SMDS_MeshElement** volumes=0);
bool CheckIntersection(const gp_Pnt& P, const gp_Pnt& PC, void LimitHeight (gp_Pnt& Papex,
gp_Pnt& Pint, SMESH_Mesh& aMesh, const gp_Pnt& PC,
const TopoDS_Shape& aShape, const TColgp_Array1OfPnt& PN,
const SMDS_MeshElement* NotCheckedFace); const std::vector<const SMDS_MeshNode*>& FNodes,
SMESH_Mesh& aMesh,
const SMDS_MeshElement* NotCheckedFace,
const bool UseApexRay);
bool Compute2ndPart(SMESH_Mesh& aMesh, bool Compute2ndPart(SMESH_Mesh& aMesh,
const std::vector<const SMDS_MeshElement*>& pyramids); const std::vector<const SMDS_MeshElement*>& pyramids);
@ -85,7 +88,8 @@ protected:
std::set<const SMDS_MeshNode*> & nodesToMove); std::set<const SMDS_MeshNode*> & nodesToMove);
void MergeAdjacent(const SMDS_MeshElement* PrmI, void MergeAdjacent(const SMDS_MeshElement* PrmI,
std::set<const SMDS_MeshNode*>& nodesToMove); std::set<const SMDS_MeshNode*>& nodesToMove,
const bool isRecursion = false);
TopoDS_Shape myShape; TopoDS_Shape myShape;