#include <Utils_CorbaException.hxx>
#include <SALOMEDS_wrap.hxx>
#include <SALOME_GenericObj_i.hh>
-#include <Basics_OCCTVersion.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRep_Tool.hxx>
#include <gp_Ax2.hxx>
#include <gp_Vec.hxx>
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
-#define NO_CAS_CATCH
-#endif
-
#include <Standard_Failure.hxx>
-
-#ifdef NO_CAS_CATCH
#include <Standard_ErrorHandler.hxx>
-#endif
#include <sstream>
#include <limits>
SMDSAbs_ElementType myPreviewType; // type to show
//!< Constructor
TPreviewMesh(SMDSAbs_ElementType previewElements = SMDSAbs_All) {
- _isShapeToMesh = (_id =_studyId = 0);
+ _isShapeToMesh = (_id = 0);
_myMeshDS = new SMESHDS_Mesh( _id, true );
myPreviewType = previewElements;
}
//=============================================================================
/*!
- * \brief Deleter of theNodeSearcher at any compute event occured
+ * \brief Deleter of theNodeSearcher at any compute event occurred
*/
//=============================================================================
//================================================================================
/*!
* \brief Increment mesh modif time and optionally record that the performed
- * modification may influence futher mesh re-compute.
+ * modification may influence further mesh re-compute.
* \param [in] isReComputeSafe - true if the modification does not influence
- * futher mesh re-compute
+ * further mesh re-compute
*/
//================================================================================
* \brief Initialize and return myPreviewMesh
* \param previewElements - type of elements to show in preview
*
- * WARNING: call it once par a method!
+ * WARNING: call it once per method!
*/
//================================================================================
//=======================================================================
/*
- * Returns description of an error/warning occured during the last operation
+ * Returns description of an error/warning occurred during the last operation
* WARNING: ComputeError.code >= 100 and no corresponding enum in IDL API
*/
//=======================================================================
*/
//=============================================================================
-CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode)
+CORBA::Long SMESH_MeshEditor_i::Add0DElement(CORBA::Long IDOfNode,
+ CORBA::Boolean DuplicateElements)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
const SMDS_MeshNode* aNode = getMeshDS()->FindNode(IDOfNode);
- SMDS_MeshElement* elem = getMeshDS()->Add0DElement(aNode);
+ SMDS_ElemIteratorPtr it0D = aNode->GetInverseElementIterator( SMDSAbs_0DElement );
+
+ SMDS_MeshElement* elem = 0;
+ if ( DuplicateElements || !it0D->more() )
+ elem = getMeshDS()->Add0DElement(aNode);
// Update Python script
TPythonDump() << "elem0d = " << this << ".Add0DElement( " << IDOfNode <<" )";
n[8],n[9],n[10],n[11],n[12],n[13],n[14],
n[15],n[16],n[17],n[18],n[19]);
break;
+ case 18:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
+ n[8],n[9],n[10],n[11],n[12],n[13],n[14],
+ n[15],n[16],n[17]);
+ break;
case 27:elem = getMeshDS()->AddVolume(n[0],n[1],n[2],n[3],n[4],n[5],n[6],n[7],
n[8],n[9],n[10],n[11],n[12],n[13],n[14],
n[15],n[16],n[17],n[18],n[19],
//=============================================================================
//
-// \brief Create 0D elements on all nodes of the given object except those
-// nodes on which a 0D element already exists.
+// \brief Create 0D elements on all nodes of the given object.
// \param theObject object on whose nodes 0D elements will be created.
// \param theGroupName optional name of a group to add 0D elements created
// and/or found on nodes of \a theObject.
+// \param DuplicateElements to add one more 0D element to a node or not.
// \return an object (a new group or a temporary SMESH_IDSource) holding
// ids of new and/or found 0D elements.
//
SMESH::SMESH_IDSource_ptr
SMESH_MeshEditor_i::Create0DElementsOnAllNodes(SMESH::SMESH_IDSource_ptr theObject,
- const char* theGroupName)
+ const char* theGroupName,
+ CORBA::Boolean theDuplicateElements)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
TIDSortedElemSet elements, elems0D;
if ( idSourceToSet( theObject, getMeshDS(), elements, SMDSAbs_All, /*emptyIfIsMesh=*/1))
- getEditor().Create0DElementsOnAllNodes( elements, elems0D );
+ getEditor().Create0DElementsOnAllNodes( elements, elems0D, theDuplicateElements );
SMESH::long_array_var newElems = new SMESH::long_array;
newElems->length( elems0D.size() );
//=============================================================================
/*!
* Find better splitting of the given quadrangle.
- * \param IDOfQuad ID of the quadrangle to be splitted.
+ * \param IDOfQuad ID of the quadrangle to be split.
* \param Criterion A criterion to choose a diagonal for splitting.
* \return 1 if 1-3 diagonal is better, 2 if 2-4
* diagonal is better, 0 if error occurs.
}
if ( !myIsPreviewMode ) {
- aPythonDump << "(" << aGroups << ", error) = "
- << this << ".ExtrusionAlongPathObjects( "
+ if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = ";
+ else aPythonDump << "(_noGroups, error) = ";
+ aPythonDump << this << ".ExtrusionAlongPathObjects( "
<< theNodes << ", "
<< theEdges << ", "
<< theFaces << ", "
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode)
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh )
- {
theTargetMesh->GetMeshDS()->Modified();
- }
else
- {
declareMeshModified( /*isReComputeSafe=*/false );
- }
}
+
return theMakeGroups ? getGroups(groupIds.get()) : 0;
SMESH_CATCH( SMESH::throwCorbaException );
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode )
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh )
- {
theTargetMesh->GetMeshDS()->Modified();
- }
else
- {
declareMeshModified( /*isReComputeSafe=*/false );
- }
}
return theMakeGroups ? getGroups(groupIds.get()) : 0;
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode)
+ if ( !myIsPreviewMode)
{
if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
else declareMeshModified( /*isReComputeSafe=*/false );
};
gp_Trsf aTrsf;
-#if OCC_VERSION_LARGE > 0x06070100
// fight against orthogonalization
// aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
// 0, S[1], 0, thePoint.y * (1-S[1]),
thePoint.z * (1-S[2]));
M.SetDiagonal( S[0], S[1], S[2] );
-#else
- double tol = std::numeric_limits<double>::max();
- aTrsf.SetValues( S[0], 0, 0, thePoint.x * (1-S[0]),
- 0, S[1], 0, thePoint.y * (1-S[1]),
- 0, 0, S[2], thePoint.z * (1-S[2]), tol, tol);
-#endif
-
TIDSortedElemSet copyElements;
TIDSortedElemSet* workElements = &elements;
if ( myIsPreviewMode )
::SMESH_MeshEditor::PGroupIDs groupIds =
getEditor().Transform (*workElements, aTrsf, theCopy, theMakeGroups, theTargetMesh);
- if ( theCopy && !myIsPreviewMode )
+ if ( !myIsPreviewMode )
{
if ( theTargetMesh ) theTargetMesh->GetMeshDS()->Modified();
else declareMeshModified( /*isReComputeSafe=*/false );
// and then "GetGroups" using SMESH_Mesh::GetGroups()
TPythonDump pydump; // to prevent dump at mesh creation
- mesh = makeMesh( theMeshName );
+ mesh = makeMesh( theMeshName );
mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
if ( mesh_i )
//=======================================================================
void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
- const SMESH::ListOfIDSources& NodesToKeep)
+ const SMESH::ListOfIDSources& NodesToKeep,
+ CORBA::Boolean AvoidMakingHoles)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
aTPythonDump << aNodeGroup;
}
- getEditor().MergeNodes( aListOfListOfNodes );
+ getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles );
- aTPythonDump << "], " << NodesToKeep << ")";
+ aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")";
declareMeshModified( /*isReComputeSafe=*/false );
return 0;
}
+//=======================================================================
+//function : IsManifold
+//purpose : Check if a 2D mesh is manifold
+//=======================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::IsManifold()
+ throw (SALOME::SALOME_Exception)
+{
+ bool isManifold = true;
+
+ SMESH_TRY;
+ SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes;
+ SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(),
+ foundFreeBordes,
+ /*closedOnly=*/true,
+ &isManifold );
+ SMESH_CATCH( SMESH::throwCorbaException );
+
+ return isManifold;
+}
+
+//=======================================================================
+//function : IsCoherentOrientation2D
+//purpose : Check if orientation of 2D elements is coherent
+//=======================================================================
+
+CORBA::Boolean SMESH_MeshEditor_i::IsCoherentOrientation2D()
+ throw (SALOME::SALOME_Exception)
+{
+ bool isGoodOri = true;
+
+ SMESH_TRY;
+ SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes;
+ SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(),
+ foundFreeBordes,
+ /*closedOnly=*/true,
+ /*isManifold=*/0,
+ &isGoodOri);
+ SMESH_CATCH( SMESH::throwCorbaException );
+
+ return isGoodOri;
+}
+
+//=======================================================================
+//function : FindFreeBorders
+//purpose : Returns all or only closed FreeBorder's.
+//=======================================================================
+
+SMESH::ListOfFreeBorders* SMESH_MeshEditor_i::FindFreeBorders(CORBA::Boolean closedOnly)
+ throw (SALOME::SALOME_Exception)
+{
+ SMESH::ListOfFreeBorders_var resBorders = new SMESH::ListOfFreeBorders;
+ SMESH_TRY;
+
+ SMESH_MeshAlgos::TFreeBorderVec foundFreeBordes;
+ SMESH_MeshAlgos::FindFreeBorders( *getMeshDS(), foundFreeBordes, closedOnly );
+
+ resBorders->length( foundFreeBordes.size() );
+ for ( size_t i = 0; i < foundFreeBordes.size(); ++i )
+ {
+ const SMESH_MeshAlgos::TFreeBorder& bordNodes = foundFreeBordes[i];
+ SMESH::FreeBorder& bordOut = resBorders[i];
+ bordOut.nodeIDs.length( bordNodes.size() );
+ for ( size_t iN = 0; iN < bordNodes.size(); ++iN )
+ bordOut.nodeIDs[ iN ] = bordNodes[ iN ]->GetID();
+ }
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+
+ return resBorders._retn();
+}
+
+//=======================================================================
+//function : FillHole
+//purpose : Fill with 2D elements a hole defined by a FreeBorder.
+//=======================================================================
+
+void SMESH_MeshEditor_i::FillHole(const SMESH::FreeBorder& theHole)
+ throw (SALOME::SALOME_Exception)
+{
+ initData();
+
+ if ( theHole.nodeIDs.length() < 4 )
+ THROW_SALOME_CORBA_EXCEPTION("A hole should be bound by at least 3 nodes", SALOME::BAD_PARAM);
+ if ( theHole.nodeIDs[0] != theHole.nodeIDs[ theHole.nodeIDs.length()-1 ] )
+ THROW_SALOME_CORBA_EXCEPTION("Not closed hole boundary. "
+ "First and last nodes must be same", SALOME::BAD_PARAM);
+
+ SMESH_MeshAlgos::TFreeBorder bordNodes;
+ bordNodes.resize( theHole.nodeIDs.length() );
+ for ( size_t iN = 0; iN < theHole.nodeIDs.length(); ++iN )
+ {
+ bordNodes[ iN ] = getMeshDS()->FindNode( theHole.nodeIDs[ iN ]);
+ if ( !bordNodes[ iN ] )
+ THROW_SALOME_CORBA_EXCEPTION(SMESH_Comment("Node #") << theHole.nodeIDs[ iN ]
+ << " does not exist", SALOME::BAD_PARAM);
+ }
+
+ SMESH_TRY;
+
+ MeshEditor_I::TPreviewMesh* previewMesh = 0;
+ SMDS_Mesh* meshDS = getMeshDS();
+ if ( myIsPreviewMode )
+ {
+ // copy faces sharing nodes of theHole
+ TIDSortedElemSet holeFaces;
+ previewMesh = getPreviewMesh( SMDSAbs_Face );
+ for ( size_t i = 0; i < bordNodes.size(); ++i )
+ {
+ SMDS_ElemIteratorPtr fIt = bordNodes[i]->GetInverseElementIterator( SMDSAbs_Face );
+ while ( fIt->more() )
+ {
+ const SMDS_MeshElement* face = fIt->next();
+ if ( holeFaces.insert( face ).second )
+ previewMesh->Copy( face );
+ }
+ bordNodes[i] = previewMesh->GetMeshDS()->FindNode( bordNodes[i]->GetID() );
+ ASSERT( bordNodes[i] );
+ }
+ meshDS = previewMesh->GetMeshDS();
+ }
+
+ std::vector<const SMDS_MeshElement*> newFaces;
+ SMESH_MeshAlgos::FillHole( bordNodes, *meshDS, newFaces );
+
+ if ( myIsPreviewMode )
+ {
+ previewMesh->Clear();
+ for ( size_t i = 0; i < newFaces.size(); ++i )
+ previewMesh->Copy( newFaces[i] );
+ }
+ else
+ {
+ getEditor().ClearLastCreated();
+ SMESH_SequenceOfElemPtr& aSeq =
+ const_cast<SMESH_SequenceOfElemPtr&>( getEditor().GetLastCreatedElems() );
+ for ( size_t i = 0; i < newFaces.size(); ++i )
+ aSeq.Append( newFaces[i] );
+
+ TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))";
+ }
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+}
+
//=======================================================================
//function : convError
//purpose :
TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
<< ide << ", " << newIDs << " )";
- MESSAGE("ChangeElementNodes");
bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
declareMeshModified( /*isReComputeSafe=*/ !res );
{
SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
SMESH::SMESH_Mesh_var mesh = gen->CreateEmptyMesh();
- SALOMEDS::Study_var study = gen->GetCurrentStudy();
- SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( study, mesh );
+ SALOMEDS::SObject_wrap meshSO = gen->ObjectToSObject( mesh );
gen->SetName( meshSO, theMeshName, "Mesh" );
gen->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED");
if ( !CORBA::is_nil( theModifiedElems ) )
aModifiedElems = theModifiedElems->GetListOfID();
else
- {
aModifiedElems = new SMESH::long_array;
- aModifiedElems->length( 0 );
- }
TPythonDump pyDump; // suppress dump by the next line
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
- MESSAGE("AffectedElemGroupsInRegion");
SMESH::ListOfGroups_var aListOfGroups = new SMESH::ListOfGroups();
- bool isEdgeGroup = false;
- bool isFaceGroup = false;
- bool isVolumeGroup = false;
- SMESH::SMESH_Group_var aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE, "affectedEdges");
- SMESH::SMESH_Group_var aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE, "affectedFaces");
- SMESH::SMESH_Group_var aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME, "affectedVolumes");
+ SMESH::SMESH_Group_var aNewEdgeGroup = SMESH::SMESH_Group::_nil();
+ SMESH::SMESH_Group_var aNewFaceGroup = SMESH::SMESH_Group::_nil();
+ SMESH::SMESH_Group_var aNewVolumeGroup = SMESH::SMESH_Group::_nil();
initData();
SMESHDS_Mesh* aMeshDS = getMeshDS();
TIDSortedElemSet anElems, aNodes;
- listOfGroupToSet(theElems, aMeshDS, anElems, false);
+ bool isNodeGrp = theElems.length() ? theElems[0]->GetType() == SMESH::NODE : false;
+ listOfGroupToSet(theElems, aMeshDS, anElems, isNodeGrp);
listOfGroupToSet(theNodesNot, aMeshDS, aNodes, true);
TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape(theShape);
TIDSortedElemSet anAffected;
bool aResult = aMeshEditor.AffectedElemGroupsInRegion(anElems, aNodes, aShape, anAffected);
-
declareMeshModified( /*isReComputeSafe=*/ !aResult );
TPythonDump pyDump;
- if (aResult)
+ if ( aResult && anAffected.size() > 0 )
{
- int lg = anAffected.size();
- MESSAGE("lg="<< lg);
SMESH::long_array_var volumeIds = new SMESH::long_array;
- volumeIds->length(lg);
- SMESH::long_array_var faceIds = new SMESH::long_array;
- faceIds->length(lg);
- SMESH::long_array_var edgeIds = new SMESH::long_array;
- edgeIds->length(lg);
+ SMESH::long_array_var faceIds = new SMESH::long_array;
+ SMESH::long_array_var edgeIds = new SMESH::long_array;
+ volumeIds->length( anAffected.size() );
+ faceIds ->length( anAffected.size() );
+ edgeIds ->length( anAffected.size() );
+
int ivol = 0;
int iface = 0;
int iedge = 0;
-
TIDSortedElemSet::const_iterator eIt = anAffected.begin();
for (; eIt != anAffected.end(); ++eIt)
{
const SMDS_MeshElement* anElem = *eIt;
- if (!anElem)
- continue;
int elemId = anElem->GetID();
- if (myMesh->GetElementType(elemId, true) == SMDSAbs_Volume)
- volumeIds[ivol++] = elemId;
- else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Face)
- faceIds[iface++] = elemId;
- else if (myMesh->GetElementType(elemId, true) == SMDSAbs_Edge)
- edgeIds[iedge++] = elemId;
+ switch ( anElem->GetType() ) {
+ case SMDSAbs_Volume: volumeIds[ivol++] = elemId; break;
+ case SMDSAbs_Face: faceIds[iface++] = elemId; break;
+ case SMDSAbs_Edge: edgeIds[iedge++] = elemId; break;
+ default:;
+ }
}
volumeIds->length(ivol);
faceIds->length(iface);
edgeIds->length(iedge);
- aNewVolumeGroup->Add(volumeIds);
- aNewFaceGroup->Add(faceIds);
- aNewEdgeGroup->Add(edgeIds);
- isVolumeGroup = (aNewVolumeGroup->Size() > 0);
- isFaceGroup = (aNewFaceGroup->Size() > 0);
- isEdgeGroup = (aNewEdgeGroup->Size() > 0);
+ int nbGroups = 0;
+ if ( ivol > 0 )
+ {
+ aNewVolumeGroup = myMesh_i->CreateGroup(SMESH::VOLUME,
+ generateGroupName("affectedVolumes").c_str());
+ aNewVolumeGroup->Add(volumeIds);
+ aListOfGroups->length( nbGroups+1 );
+ aListOfGroups[ nbGroups++ ] = aNewVolumeGroup._retn();
+ }
+ if ( iface > 0 )
+ {
+ aNewFaceGroup = myMesh_i->CreateGroup(SMESH::FACE,
+ generateGroupName("affectedFaces").c_str());
+ aNewFaceGroup->Add(faceIds);
+ aListOfGroups->length( nbGroups+1 );
+ aListOfGroups[ nbGroups++ ] = aNewFaceGroup._retn();
+ }
+ if ( iedge > 0 )
+ {
+ aNewEdgeGroup = myMesh_i->CreateGroup(SMESH::EDGE,
+ generateGroupName("affectedEdges").c_str());
+ aNewEdgeGroup->Add(edgeIds);
+ aListOfGroups->length( nbGroups+1 );
+ aListOfGroups[ nbGroups++ ] = aNewEdgeGroup._retn();
+ }
}
- int nbGroups = 0;
- if (isEdgeGroup) nbGroups++;
- if (isFaceGroup) nbGroups++;
- if (isVolumeGroup) nbGroups++;
- aListOfGroups->length(nbGroups);
-
- int i = 0;
- if (isEdgeGroup) aListOfGroups[i++] = aNewEdgeGroup._retn();
- if (isFaceGroup) aListOfGroups[i++] = aNewFaceGroup._retn();
- if (isVolumeGroup) aListOfGroups[i++] = aNewVolumeGroup._retn();
-
// Update Python script
- pyDump << "[ ";
- if (isEdgeGroup) pyDump << aNewEdgeGroup << ", ";
- if (isFaceGroup) pyDump << aNewFaceGroup << ", ";
- if (isVolumeGroup) pyDump << aNewVolumeGroup << ", ";
- pyDump << "] = ";
- pyDump << this << ".AffectedElemGroupsInRegion( "
+ pyDump << aListOfGroups << " = " << this << ".AffectedElemGroupsInRegion( "
<< &theElems << ", " << &theNodesNot << ", " << theShape << " )";
return aListOfGroups._retn();
//================================================================================
/*!
\brief Generated skin mesh (containing 2D cells) from 3D mesh
- The created 2D mesh elements based on nodes of free faces of boundary volumes
+ The created 2D mesh elements based on nodes of free faces of boundary volumes
\return TRUE if operation has been completed successfully, FALSE otherwise
*/
//================================================================================
else
pyDump << mesh_var << ", ";
if ( group_var->_is_nil() )
- pyDump << "_NoneGroup = "; // assignment to None is forbiden
+ pyDump << "_NoneGroup = "; // assignment to None is forbidden
else
pyDump << group_var << " = ";
pyDump << this << ".MakeBoundaryMesh( "
else
groupsOfThisMesh[ nbGroups++ ] = groups[i];
if ( SMESH::DownCast<SMESH_Mesh_i*>( groups[i] ))
- THROW_SALOME_CORBA_EXCEPTION("expect a group but recieve a mesh", SALOME::BAD_PARAM);
+ THROW_SALOME_CORBA_EXCEPTION("expected a group but received a mesh", SALOME::BAD_PARAM);
}
groupsOfThisMesh->length( nbGroups );
groupsOfOtherMesh->length( nbGroupsOfOtherMesh );
else
pyDump << mesh_var << ", ";
if ( group_var->_is_nil() )
- pyDump << "_NoneGroup = "; // assignment to None is forbiden
+ pyDump << "_NoneGroup = "; // assignment to None is forbidden
else
pyDump << group_var << " = ";
pyDump << this << ".MakeBoundaryElements( "
SMESH_CATCH( SMESH::throwCorbaException );
return 0;
}
+
+//================================================================================
+/*!
+ * \brief Create a polyline consisting of 1D mesh elements each lying on a 2D element of
+ * the initial mesh. Positions of new nodes are found by cutting the mesh by the
+ * plane passing through pairs of points specified by each PolySegment structure.
+ * If there are several paths connecting a pair of points, the shortest path is
+ * selected by the module. Position of the cutting plane is defined by the two
+ * points and an optional vector lying on the plane specified by a PolySegment.
+ * By default the vector is defined by Mesh module as following. A middle point
+ * of the two given points is computed. The middle point is projected to the mesh.
+ * The vector goes from the middle point to the projection point. In case of planar
+ * mesh, the vector is normal to the mesh.
+ * \param [inout] segments - PolySegment's defining positions of cutting planes.
+ * Return the used vector and position of the middle point.
+ * \param [in] groupName - optional name of a group where created mesh segments will
+ * be added.
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::MakePolyLine(SMESH::ListOfPolySegments& theSegments,
+ const char* theGroupName)
+ throw (SALOME::SALOME_Exception)
+{
+ if ( theSegments.length() == 0 )
+ THROW_SALOME_CORBA_EXCEPTION("No segments given", SALOME::BAD_PARAM );
+ if ( myMesh->NbFaces() == 0 )
+ THROW_SALOME_CORBA_EXCEPTION("No faces in the mesh", SALOME::BAD_PARAM );
+
+ SMESH_TRY;
+ initData(/*deleteSearchers=*/false);
+
+ SMESHDS_Group* groupDS = 0;
+ SMESHDS_Mesh* meshDS = getMeshDS();
+ if ( myIsPreviewMode ) // copy faces to the tmp mesh
+ {
+ TPreviewMesh * tmpMesh = getPreviewMesh( SMDSAbs_Edge );
+ SMDS_ElemIteratorPtr faceIt = getMeshDS()->elementsIterator( SMDSAbs_Face );
+ while ( faceIt->more() )
+ tmpMesh->Copy( faceIt->next() );
+ meshDS = tmpMesh->GetMeshDS();
+ }
+ else if ( theGroupName[0] ) // find/create a group of segments
+ {
+ SMESH_Mesh::GroupIteratorPtr grpIt = myMesh->GetGroups();
+ while ( !groupDS && grpIt->more() )
+ {
+ SMESH_Group* group = grpIt->next();
+ if ( group->GetGroupDS()->GetType() == SMDSAbs_Edge &&
+ strcmp( group->GetName(), theGroupName ) == 0 )
+ {
+ groupDS = dynamic_cast< SMESHDS_Group* >( group->GetGroupDS() );
+ }
+ }
+ if ( !groupDS )
+ {
+ SMESH::SMESH_Group_var groupVar = myMesh_i->CreateGroup( SMESH::EDGE, theGroupName );
+
+ if ( SMESH_Group_i* groupImpl = SMESH::DownCast<SMESH_Group_i*>( groupVar ))
+ groupDS = dynamic_cast< SMESHDS_Group* >( groupImpl->GetGroupDS() );
+ }
+ }
+
+ // convert input polySegments
+ ::SMESH_MeshEditor::TListOfPolySegments segments( theSegments.length() );
+ for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+ {
+ SMESH::PolySegment& segIn = theSegments[ i ];
+ ::SMESH_MeshEditor::PolySegment& segOut = segments[ i ];
+ segOut.myNode1[0] = meshDS->FindNode( segIn.node1ID1 );
+ segOut.myNode2[0] = meshDS->FindNode( segIn.node1ID2 );
+ segOut.myNode1[1] = meshDS->FindNode( segIn.node2ID1 );
+ segOut.myNode2[1] = meshDS->FindNode( segIn.node2ID2 );
+ segOut.myVector.SetCoord( segIn.vector.PS.x,
+ segIn.vector.PS.y,
+ segIn.vector.PS.z );
+ if ( !segOut.myNode1[0] )
+ THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node1ID1,
+ SALOME::BAD_PARAM );
+ if ( !segOut.myNode1[1] )
+ THROW_SALOME_CORBA_EXCEPTION( SMESH_Comment( "Invalid node ID: ") << segIn.node2ID1,
+ SALOME::BAD_PARAM );
+ }
+
+ // get a static ElementSearcher
+ SMESH::SMESH_IDSource_var idSource = SMESH::SMESH_IDSource::_narrow( myMesh_i->_this() );
+ theSearchersDeleter.Set( myMesh, getPartIOR( idSource, SMESH::FACE ));
+ if ( !theElementSearcher )
+ theElementSearcher = SMESH_MeshAlgos::GetElementSearcher( *getMeshDS() );
+
+ // compute
+ getEditor().MakePolyLine( segments, groupDS, theElementSearcher );
+
+ // return vectors
+ if ( myIsPreviewMode )
+ {
+ for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+ {
+ SMESH::PolySegment& segOut = theSegments[ i ];
+ ::SMESH_MeshEditor::PolySegment& segIn = segments[ i ];
+ segOut.vector.PS.x = segIn.myVector.X();
+ segOut.vector.PS.y = segIn.myVector.Y();
+ segOut.vector.PS.z = segIn.myVector.Z();
+ }
+ }
+ else
+ {
+ TPythonDump() << "_segments = []";
+ for ( CORBA::ULong i = 0; i < theSegments.length(); ++i )
+ {
+ SMESH::PolySegment& segIn = theSegments[ i ];
+ TPythonDump() << "_segments.append( SMESH.PolySegment( "
+ << segIn.node1ID1 << ", "
+ << segIn.node1ID2 << ", "
+ << segIn.node2ID1 << ", "
+ << segIn.node2ID2 << ", "
+ << "smeshBuilder.MakeDirStruct( "
+ << segIn.vector.PS.x << ", "
+ << segIn.vector.PS.y << ", "
+ << segIn.vector.PS.z << ")))";
+ }
+ TPythonDump() << this << ".MakePolyLine( _segments, '" << theGroupName << "')";
+ }
+ meshDS->Modified();
+ SMESH_CATCH( SMESH::throwCorbaException );
+ return;
+}