-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
#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>
}
// creates a corresponding element on copied nodes
- SMDS_MeshElement* anElemCopy = 0;
- if ( anElem->IsPoly() && anElem->GetType() == SMDSAbs_Volume )
- {
- const SMDS_VtkVolume* ph =
- dynamic_cast<const SMDS_VtkVolume*> (anElem);
- if ( ph )
- anElemCopy = _myMeshDS->AddPolyhedralVolumeWithID
- (anElemNodesID, ph->GetQuantities(),anElem->GetID());
- }
- else {
- anElemCopy = ::SMESH_MeshEditor(this).AddElement( anElemNodesID,
- anElem->GetType(),
- anElem->IsPoly() );
- }
+ ::SMESH_MeshEditor::ElemFeatures elemType;
+ elemType.Init( anElem, /*basicOnly=*/false );
+ elemType.SetID( anElem->GetID() );
+ SMDS_MeshElement* anElemCopy =
+ ::SMESH_MeshEditor(this).AddElement( anElemNodesID, elemType );
return anElemCopy;
}
//!< Copy a node
}
void Remove( SMDSAbs_ElementType type )
{
- SMDS_ElemIteratorPtr eIt = GetMeshDS()->elementsIterator( type );
+ Remove( GetMeshDS()->elementsIterator( type ));
+ }
+ void Remove( SMDS_ElemIteratorPtr eIt )
+ {
while ( eIt->more() )
GetMeshDS()->RemoveFreeElement( eIt->next(), /*sm=*/0, /*fromGroups=*/false );
}
//=============================================================================
/*!
- * \brief Deleter of theNodeSearcher at any compute event occured
+ * \brief Deleter of theNodeSearcher at any compute event occurred
*/
//=============================================================================
SMDS_MeshElement::Filter & filter = *aFilter;
if ( aType == SMDSAbs_Node )
- for (int i=0; i<IDs.length(); i++) {
+ for ( CORBA::ULong i = 0; i < IDs.length(); i++ ) {
const SMDS_MeshElement * elem = aMesh->FindNode( IDs[i] );
if ( filter( elem ))
aMap.insert( aMap.end(), elem );
}
else
- for (int i=0; i<IDs.length(); i++) {
+ for ( CORBA::ULong i = 0; i<IDs.length(); i++) {
const SMDS_MeshElement * elem = aMesh->FindElement( IDs[i] );
if ( filter( elem ))
aMap.insert( aMap.end(), elem );
SMESH::long_array_var aElementsId = theObject->GetIDs();
if ( types->length() == 1 && types[0] == SMESH::NODE)
{
- for(int i = 0; i < aElementsId->length(); i++)
+ for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
if ( const SMDS_MeshNode * n = theMeshDS->FindNode( aElementsId[i] ))
theNodeSet.insert( theNodeSet.end(), n);
}
{
SMDS_NodeIteratorPtr nIt = theMeshDS->nodesIterator();
while ( nIt->more( ))
- if( const SMDS_MeshElement * elem = nIt->next() )
+ if ( const SMDS_MeshElement * elem = nIt->next() )
theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
}
else
{
- for(int i = 0; i < aElementsId->length(); i++)
- if( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
+ for ( CORBA::ULong i = 0; i < aElementsId->length(); i++ )
+ if ( const SMDS_MeshElement * elem = theMeshDS->FindElement( aElementsId[i] ))
theNodeSet.insert( elem->begin_nodes(), elem->end_nodes());
}
}
SMDSAbs_ElementType elemType = (*theElements.begin())->GetType();
bool sameElemType = ( elemType == (*theElements.rbegin())->GetType() );
if ( sameElemType &&
- theMeshDS->GetMeshInfo().NbElements( elemType ) == theElements.size() )
+ theMeshDS->GetMeshInfo().NbElements( elemType ) == (int) theElements.size() )
return; // all the elements are in theElements
if ( !sameElemType )
//================================================================================
/*!
* \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!
*/
//================================================================================
SMESH::MeshPreviewStruct* SMESH_MeshEditor_i::GetPreviewData()
throw (SALOME::SALOME_Exception)
-{
+{
SMESH_TRY;
const bool hasBadElems = ( getEditor().GetError() && getEditor().GetError()->HasBadElems() );
- if ( myIsPreviewMode || hasBadElems ) { // --- MeshPreviewStruct filling ---
-
+ if ( myIsPreviewMode || hasBadElems )
+ {
list<int> aNodesConnectivity;
typedef map<int, int> TNodesMap;
TNodesMap nodesMap;
SMESHDS_Mesh* aMeshDS;
- std::auto_ptr< SMESH_MeshPartDS > aMeshPartDS;
+ std::unique_ptr< SMESH_MeshPartDS > aMeshPartDS;
if ( hasBadElems ) {
aMeshPartDS.reset( new SMESH_MeshPartDS( getEditor().GetError()->myBadElements ));
aMeshDS = aMeshPartDS.get();
myPreviewData = new SMESH::MeshPreviewStruct();
myPreviewData->nodesXYZ.length(aMeshDS->NbNodes());
-
+
SMDSAbs_ElementType previewType = SMDSAbs_All;
if ( !hasBadElems )
if (TPreviewMesh * aPreviewMesh = dynamic_cast< TPreviewMesh* >( getEditor().GetMesh() )) {
while ( itMeshElems->more() ) {
const SMDS_MeshElement* aMeshElem = itMeshElems->next();
- SMDS_NodeIteratorPtr itElemNodes = aMeshElem->nodeIterator();
+ SMDS_NodeIteratorPtr itElemNodes =
+ (( aMeshElem->GetEntityType() == SMDSEntity_Quad_Polygon ) ?
+ aMeshElem->interlacedNodesIterator() :
+ aMeshElem->nodeIterator() );
while ( itElemNodes->more() ) {
const SMDS_MeshNode* aMeshNode = itElemNodes->next();
int aNodeID = aMeshNode->GetID();
SMESH::long_array_var myLastCreatedNodes = new SMESH::long_array();
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedNodes();
- myLastCreatedNodes->length( aSeq.Length() );
- for (int i = 1; i <= aSeq.Length(); i++)
- myLastCreatedNodes[i-1] = aSeq.Value(i)->GetID();
+ myLastCreatedNodes->length( aSeq.size() );
+ for ( size_t i = 0; i < aSeq.size(); i++)
+ myLastCreatedNodes[i] = aSeq[i]->GetID();
return myLastCreatedNodes._retn();
SMESH_CATCH( SMESH::throwCorbaException );
SMESH::long_array_var myLastCreatedElems = new SMESH::long_array();
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
- myLastCreatedElems->length( aSeq.Length() );
- for ( int i = 1; i <= aSeq.Length(); i++ )
- myLastCreatedElems[i-1] = aSeq.Value(i)->GetID();
+ myLastCreatedElems->length( aSeq.size() );
+ for ( size_t i = 0; i < aSeq.size(); i++ )
+ myLastCreatedElems[i] = aSeq[i]->GetID();
return myLastCreatedElems._retn();
SMESH_CATCH( SMESH::throwCorbaException );
//=======================================================================
/*
- * 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
*/
//=======================================================================
list< int > IdList;
- for (int i = 0; i < IDsOfElements.length(); i++)
+ for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
IdList.push_back( IDsOfElements[i] );
// Update Python script
initData();
list< int > IdList;
- for (int i = 0; i < IDsOfNodes.length(); i++)
+ for ( CORBA::ULong i = 0; i < IDsOfNodes.length(); i++)
IdList.push_back( IDsOfNodes[i] );
// Update Python script
SMESH::Controls::Filter::GetElementsId( getMeshDS(), predicate, seq );
// remove orphan nodes (if there are any)
- list< int > IdList;
- for ( int i = 0; i < seq.size(); i++ )
- IdList.push_back( seq[i] );
+ list< int > IdList( seq.begin(), seq.end() );
int nbNodesBefore = myMesh->NbNodes();
getEditor().Remove( IdList, true );
*/
//=============================================================================
-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 <<" )";
* AddPolygonalFace
*/
//=============================================================================
+
CORBA::Long SMESH_MeshEditor_i::AddPolygonalFace (const SMESH::long_array & IDsOfNodes)
throw (SALOME::SALOME_Exception)
{
int NbNodes = IDsOfNodes.length();
std::vector<const SMDS_MeshNode*> nodes (NbNodes);
for (int i = 0; i < NbNodes; i++)
- nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
+ if ( ! ( nodes[i] = getMeshDS()->FindNode( IDsOfNodes[i] )))
+ return 0;
const SMDS_MeshElement* elem = getMeshDS()->AddPolygonalFace(nodes);
return 0;
}
+//=============================================================================
+/*!
+ * AddQuadPolygonalFace
+ */
+//=============================================================================
+
+CORBA::Long SMESH_MeshEditor_i::AddQuadPolygonalFace (const SMESH::long_array & IDsOfNodes)
+ throw (SALOME::SALOME_Exception)
+{
+ SMESH_TRY;
+ initData();
+
+ int NbNodes = IDsOfNodes.length();
+ std::vector<const SMDS_MeshNode*> nodes (NbNodes);
+ for (int i = 0; i < NbNodes; i++)
+ nodes[i] = getMeshDS()->FindNode(IDsOfNodes[i]);
+
+ const SMDS_MeshElement* elem = getMeshDS()->AddQuadPolygonalFace(nodes);
+
+ // Update Python script
+ TPythonDump() <<"faceID = "<<this<<".AddPolygonalFace( "<<IDsOfNodes<<" )";
+
+ declareMeshModified( /*isReComputeSafe=*/false );
+ return elem ? elem->GetID() : 0;
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+ return 0;
+}
+
//=============================================================================
/*!
* Create volume, either linear and quadratic (this is determed
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() );
SMESH_TRY;
initData();
- for (int i = 0; i < IDsOfElements.length(); i++)
+ for ( CORBA::ULong i = 0; i < IDsOfElements.length(); i++ )
{
CORBA::Long index = IDsOfElements[i];
const SMDS_MeshElement * elem = getMeshDS()->FindElement(index);
//=============================================================================
/*!
* 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.
*/
//================================================================================
-void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms (SMESH::SMESH_IDSource_ptr elems,
+void SMESH_MeshEditor_i::SplitHexahedraIntoPrisms( SMESH::SMESH_IDSource_ptr elems,
const SMESH::PointStruct & startHexPoint,
const SMESH::DirStruct& facetToSplitNormal,
CORBA::Short methodFlags,
SMESH_CATCH( SMESH::throwCorbaException );
}
+//================================================================================
+/*!
+ * \brief Split bi-quadratic elements into linear ones without creation of additional nodes:
+ * - bi-quadratic triangle will be split into 3 linear quadrangles;
+ * - bi-quadratic quadrangle will be split into 4 linear quadrangles;
+ * - tri-quadratic hexahedron will be split into 8 linear hexahedra.
+ * Quadratic elements of lower dimension adjacent to the split bi-quadratic element
+ * will be split in order to keep the mesh conformal.
+ * \param elems - elements to split
+ */
+//================================================================================
+
+void SMESH_MeshEditor_i::SplitBiQuadraticIntoLinear(const SMESH::ListOfIDSources& theElems)
+ throw (SALOME::SALOME_Exception)
+{
+ SMESH_TRY;
+ initData();
+
+ TIDSortedElemSet elemSet;
+ for ( size_t i = 0; i < theElems.length(); ++i )
+ {
+ SMESH::SMESH_IDSource_ptr elems = theElems[i].in();
+ SMESH::SMESH_Mesh_var mesh = elems->GetMesh();
+ if ( mesh->GetId() != myMesh_i->GetId() )
+ THROW_SALOME_CORBA_EXCEPTION("Wrong mesh of IDSource", SALOME::BAD_PARAM);
+
+ idSourceToSet( elems, getMeshDS(), elemSet, SMDSAbs_All );
+ }
+ getEditor().SplitBiQuadraticIntoLinear( elemSet );
+
+ declareMeshModified( /*isReComputeSafe=*/true ); // it does not influence Compute()
+
+ TPythonDump() << this << ".SplitBiQuadraticIntoLinear( "
+ << theElems << " )";
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+}
+
//=======================================================================
//function : Smooth
//purpose :
arrayToSet(IDsOfElements, aMesh, elements, SMDSAbs_Face);
set<const SMDS_MeshNode*> fixedNodes;
- for (int i = 0; i < IDsOfFixedNodes.length(); i++) {
+ for ( CORBA::ULong i = 0; i < IDsOfFixedNodes.length(); i++) {
CORBA::Long index = IDsOfFixedNodes[i];
const SMDS_MeshNode * node = aMesh->FindNode(index);
if ( node )
bool myIsExtrusionByNormal;
static int makeFlags( CORBA::Boolean MakeGroups,
+ CORBA::Boolean LinearVariation = false,
CORBA::Boolean ByAverageNormal = false,
CORBA::Boolean UseInputElemsOnly = false,
CORBA::Long Flags = 0,
if ( MakeGroups ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS;
if ( ByAverageNormal ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BY_AVG_NORMAL;
if ( UseInputElemsOnly) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY;
+ if ( LinearVariation ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_SCALE_LINEAR_VARIATION;
if ( MakeBoundary ) Flags |= ::SMESH_MeshEditor::EXTRUSION_FLAG_BOUNDARY;
return Flags;
}
// standard params
- ExtrusionParams(const SMESH::DirStruct & theDir,
- CORBA::Long theNbOfSteps,
- CORBA::Boolean theMakeGroups):
+ ExtrusionParams(const SMESH::DirStruct & theDir,
+ CORBA::Long theNbOfSteps,
+ const SMESH::double_array & theScaleFactors,
+ CORBA::Boolean theLinearVariation,
+ const SMESH::double_array & theBasePoint,
+ CORBA::Boolean theMakeGroups):
::SMESH_MeshEditor::ExtrusParam ( gp_Vec( theDir.PS.x,
theDir.PS.y,
theDir.PS.z ),
theNbOfSteps,
- makeFlags( theMakeGroups )),
+ toList( theScaleFactors ),
+ TBasePoint( theBasePoint ),
+ makeFlags( theMakeGroups, theLinearVariation )),
myIsExtrusionByNormal( false )
{
}
theDir.PS.y,
theDir.PS.z ),
theNbOfSteps,
- makeFlags( theMakeGroups, false, false,
+ std::list<double>(),
+ 0,
+ makeFlags( theMakeGroups, false, false, false,
theExtrFlags, false ),
theSewTolerance ),
myIsExtrusionByNormal( false )
CORBA::Boolean theMakeGroups ):
::SMESH_MeshEditor::ExtrusParam ( theStepSize,
theNbOfSteps,
- makeFlags( theMakeGroups,
+ makeFlags( theMakeGroups, false,
theByAverageNormal, theUseInputElemsOnly ),
theDim),
myIsExtrusionByNormal( true )
{
Flags() &= ~(::SMESH_MeshEditor::EXTRUSION_FLAG_GROUPS);
}
+
+ private:
+
+ static std::list<double> toList( const SMESH::double_array & theScaleFactors )
+ {
+ std::list<double> scales;
+ for ( CORBA::ULong i = 0; i < theScaleFactors.length(); ++i )
+ scales.push_back( theScaleFactors[i] );
+ return scales;
+ }
+
+ // structure used to convert SMESH::double_array to gp_XYZ*
+ struct TBasePoint
+ {
+ gp_XYZ *pp, p;
+ TBasePoint( const SMESH::double_array & theBasePoint )
+ {
+ pp = 0;
+ if ( theBasePoint.length() == 3 )
+ {
+ p.SetCoord( theBasePoint[0], theBasePoint[1], theBasePoint[2] );
+ pp = &p;
+ }
+ }
+ operator const gp_XYZ*() const { return pp; }
+ };
};
}
const SMESH::ListOfIDSources & theFaces,
const SMESH::DirStruct & theStepVector,
CORBA::Long theNbOfSteps,
+ const SMESH::double_array & theScaleFactors,
+ CORBA::Boolean theLinearVariation,
+ const SMESH::double_array & theBasePoint,
CORBA::Boolean theToMakeGroups)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
- ExtrusionParams params( theStepVector, theNbOfSteps, theToMakeGroups );
+ ExtrusionParams params( theStepVector, theNbOfSteps, theScaleFactors,
+ theLinearVariation, theBasePoint, theToMakeGroups );
TIDSortedElemSet elemsNodes[2];
for ( int i = 0, nb = theNodes.length(); i < nb; ++i ) {
if ( !aMeshImp ) return aGroups._retn();
TopoDS_Shape aShape = SMESH_Gen_i::GetSMESHGen()->GeomObjectToShape( thePathShape );
aSubMesh = aMeshImp->GetImpl().GetSubMesh( aShape );
- if ( !aSubMesh || !aSubMesh->GetSubMeshDS() )
+ if ( !aSubMesh /*|| !aSubMesh->GetSubMeshDS()*/ )
return aGroups._retn();
}
idSourceToSet( theFaces[i], getMeshDS(), elemsNodes[0], SMDSAbs_Face );
list<double> angles;
- for (int i = 0; i < theAngles.length(); i++) {
+ for ( CORBA::ULong i = 0; i < theAngles.length(); i++ ) {
angles.push_back( theAngles[i] );
}
}
if ( !myIsPreviewMode ) {
- aPythonDump << "(" << aGroups << ", error) = "
- << this << ".ExtrusionAlongPathObjects( "
+ if ( aGroups->length() > 0 ) aPythonDump << "(" << aGroups << ", error) = ";
+ else aPythonDump << "(_noGroups, error) = ";
+ aPythonDump << this << ".ExtrusionAlongPathObjects( "
<< theNodes << ", "
<< theEdges << ", "
<< theFaces << ", "
<< thePathShape << ", "
<< theNodeStart << ", "
<< theHasAngles << ", "
- << theAngles << ", "
+ << TVar( theAngles ) << ", "
<< theLinearVariation << ", "
<< theHasRefPoint << ", "
<< "SMESH.PointStruct( "
- << ( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
- << ( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
- << ( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
+ << TVar( theHasRefPoint ? theRefPoint.x : 0 ) << ", "
+ << TVar( theHasRefPoint ? theRefPoint.y : 0 ) << ", "
+ << TVar( theHasRefPoint ? theRefPoint.z : 0 ) << " ), "
<< theMakeGroups << " )";
}
else
::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 )
return mesh._retn();
}
+//================================================================================
+/*!
+ * \brief Make an offset mesh from a source 2D mesh
+ * \param [inout] theObject - source mesh. New elements are added to this mesh
+ * if \a theMeshName is empty.
+ * \param [in] theValue - offset value
+ * \param [in] theCopyGroups - to generate groups
+ * \param [in] theMeshName - optional name of a new mesh
+ * \param [out] theGroups - new groups
+ * \return SMESH::SMESH_Mesh_ptr - the modified mesh
+ */
+//================================================================================
-//=======================================================================
-//function : FindCoincidentNodes
-//purpose :
-//=======================================================================
-
-void SMESH_MeshEditor_i::FindCoincidentNodes (CORBA::Double Tolerance,
- SMESH::array_of_long_array_out GroupsOfNodes)
+SMESH::SMESH_Mesh_ptr SMESH_MeshEditor_i::Offset( SMESH::SMESH_IDSource_ptr theObject,
+ CORBA::Double theValue,
+ CORBA::Boolean theCopyGroups,
+ const char* theMeshName,
+ SMESH::ListOfGroups_out theGroups)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
initData();
+ SMESHDS_Mesh* aMeshDS = getMeshDS();
+
+ SMESH::SMESH_Mesh_var mesh_var;
+ ::SMESH_MeshEditor::PGroupIDs groupIds;
+
+ TPythonDump pyDump;
+
+ TIDSortedElemSet elements, copyElements;
+ if ( idSourceToSet( theObject, aMeshDS, elements, SMDSAbs_Face,
+ /*emptyIfIsMesh=*/ !myIsPreviewMode ))
+ {
+ // mesh to modify
+ SMESH_Mesh* tgtMesh = 0;
+ if ( myIsPreviewMode )
+ {
+ TPreviewMesh * tmpMesh = getPreviewMesh();
+ tgtMesh = tmpMesh;
+ tmpMesh->Copy( elements, copyElements );
+ theCopyGroups = false;
+ }
+ else
+ {
+ mesh_var =
+ *theMeshName ? makeMesh( theMeshName ) : SMESH::SMESH_Mesh::_duplicate( myMesh_i->_this() );
+ SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh_var );
+ tgtMesh = & mesh_i->GetImpl();
+ }
+ groupIds = getEditor().Offset( elements, theValue, tgtMesh, theCopyGroups, !myIsPreviewMode );
+
+ tgtMesh->GetMeshDS()->Modified();
+ }
+
+ if ( myIsPreviewMode )
+ {
+ getPreviewMesh()->Remove( SMESHUtils::elemSetIterator( copyElements ));
+ }
+ else
+ {
+ theGroups = theCopyGroups ? getGroups( groupIds.get() ) : new SMESH::ListOfGroups;
+
+ // result of Offset() is a tuple (mesh, groups)
+ if ( mesh_var->_is_nil() ) pyDump << myMesh_i->_this() << ", ";
+ else pyDump << mesh_var << ", ";
+ pyDump << theGroups << " = "
+ << this << ".Offset( "
+ << theValue << ", "
+ << theCopyGroups << ", "
+ << "'" << theMeshName<< "')";
+ }
+
+ return mesh_var._retn();
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+ return SMESH::SMESH_Mesh::_nil();
+}
+
+//=======================================================================
+//function : findCoincidentNodes
+//purpose :
+//=======================================================================
+
+void SMESH_MeshEditor_i::
+findCoincidentNodes (TIDSortedNodeSet & Nodes,
+ CORBA::Double Tolerance,
+ SMESH::array_of_long_array_out GroupsOfNodes,
+ CORBA::Boolean SeparateCornersAndMedium)
+{
::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
- TIDSortedNodeSet nodes; // no input nodes
- getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+ getEditor().FindCoincidentNodes( Nodes, Tolerance, aListOfListOfNodes, SeparateCornersAndMedium );
GroupsOfNodes = new SMESH::array_of_long_array;
GroupsOfNodes->length( aListOfListOfNodes.size() );
::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
- for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ ) {
+ for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
+ {
list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
aGroup[ j ] = (*lIt)->GetID();
}
+}
+
+//=======================================================================
+//function : FindCoincidentNodes
+//purpose :
+//=======================================================================
+
+void SMESH_MeshEditor_i::
+FindCoincidentNodes (CORBA::Double Tolerance,
+ SMESH::array_of_long_array_out GroupsOfNodes,
+ CORBA::Boolean SeparateCornersAndMedium)
+ throw (SALOME::SALOME_Exception)
+{
+ SMESH_TRY;
+ initData();
+
+ TIDSortedNodeSet nodes; // no input nodes
+ findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
+
TPythonDump() << "coincident_nodes = " << this << ".FindCoincidentNodes( "
- << Tolerance << " )";
+ << Tolerance << ", "
+ << SeparateCornersAndMedium << " )";
SMESH_CATCH( SMESH::throwCorbaException );
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor_i::FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
- CORBA::Double Tolerance,
- SMESH::array_of_long_array_out GroupsOfNodes)
+void SMESH_MeshEditor_i::
+FindCoincidentNodesOnPart(SMESH::SMESH_IDSource_ptr theObject,
+ CORBA::Double Tolerance,
+ SMESH::array_of_long_array_out GroupsOfNodes,
+ CORBA::Boolean SeparateCornersAndMedium)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
TIDSortedNodeSet nodes;
idSourceToNodeSet( theObject, getMeshDS(), nodes );
- ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
- if(!nodes.empty())
- getEditor().FindCoincidentNodes( nodes, Tolerance, aListOfListOfNodes );
+ findCoincidentNodes( nodes, Tolerance, GroupsOfNodes, SeparateCornersAndMedium );
- GroupsOfNodes = new SMESH::array_of_long_array;
- GroupsOfNodes->length( aListOfListOfNodes.size() );
- ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
- for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
- {
- list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
- list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
- SMESH::long_array& aGroup = (*GroupsOfNodes)[ i ];
- aGroup.length( aListOfNodes.size() );
- for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
- aGroup[ j ] = (*lIt)->GetID();
- }
TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPart( "
- <<theObject<<", "
- << Tolerance << " )";
+ << theObject <<", "
+ << Tolerance << ", "
+ << SeparateCornersAndMedium << " )";
SMESH_CATCH( SMESH::throwCorbaException );
}
FindCoincidentNodesOnPartBut(SMESH::SMESH_IDSource_ptr theObject,
CORBA::Double theTolerance,
SMESH::array_of_long_array_out theGroupsOfNodes,
- const SMESH::ListOfIDSources& theExceptSubMeshOrGroups)
+ const SMESH::ListOfIDSources& theExceptSubMeshOrGroups,
+ CORBA::Boolean theSeparateCornersAndMedium)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
TIDSortedNodeSet nodes;
idSourceToNodeSet( theObject, getMeshDS(), nodes );
- for ( int i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
+ for ( CORBA::ULong i = 0; i < theExceptSubMeshOrGroups.length(); ++i )
{
- TIDSortedNodeSet exceptNodes;
- idSourceToNodeSet( theExceptSubMeshOrGroups[i], getMeshDS(), exceptNodes );
- TIDSortedNodeSet::iterator avoidNode = exceptNodes.begin();
- for ( ; avoidNode != exceptNodes.end(); ++avoidNode)
- nodes.erase( *avoidNode );
+ SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( theExceptSubMeshOrGroups[i],
+ SMESH::NODE );
+ while ( nodeIt->more() )
+ nodes.erase( cast2Node( nodeIt->next() ));
}
- ::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
- if(!nodes.empty())
- getEditor().FindCoincidentNodes( nodes, theTolerance, aListOfListOfNodes );
+ findCoincidentNodes( nodes, theTolerance, theGroupsOfNodes, theSeparateCornersAndMedium );
- theGroupsOfNodes = new SMESH::array_of_long_array;
- theGroupsOfNodes->length( aListOfListOfNodes.size() );
- ::SMESH_MeshEditor::TListOfListOfNodes::iterator llIt = aListOfListOfNodes.begin();
- for ( CORBA::Long i = 0; llIt != aListOfListOfNodes.end(); llIt++, i++ )
- {
- list< const SMDS_MeshNode* >& aListOfNodes = *llIt;
- list< const SMDS_MeshNode* >::iterator lIt = aListOfNodes.begin();;
- SMESH::long_array& aGroup = (*theGroupsOfNodes)[ i ];
- aGroup.length( aListOfNodes.size() );
- for ( int j = 0; lIt != aListOfNodes.end(); lIt++, j++ )
- aGroup[ j ] = (*lIt)->GetID();
- }
TPythonDump() << "coincident_nodes_on_part = " << this << ".FindCoincidentNodesOnPartBut( "
<< theObject<<", "
<< theTolerance << ", "
- << theExceptSubMeshOrGroups << " )";
+ << theExceptSubMeshOrGroups << ", "
+ << theSeparateCornersAndMedium << " )";
SMESH_CATCH( SMESH::throwCorbaException );
}
//purpose :
//=======================================================================
-void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes)
+void SMESH_MeshEditor_i::MergeNodes (const SMESH::array_of_long_array& GroupsOfNodes,
+ const SMESH::ListOfIDSources& NodesToKeep,
+ CORBA::Boolean AvoidMakingHoles)
throw (SALOME::SALOME_Exception)
{
SMESH_TRY;
TPythonDump aTPythonDump;
aTPythonDump << this << ".MergeNodes([";
+
+ TIDSortedNodeSet setOfNodesToKeep;
+ for ( CORBA::ULong i = 0; i < NodesToKeep.length(); ++i )
+ {
+ prepareIdSource( NodesToKeep[i] );
+ SMDS_ElemIteratorPtr nodeIt = myMesh_i->GetElements( NodesToKeep[i], SMESH::NODE );
+ while ( nodeIt->more() )
+ setOfNodesToKeep.insert( setOfNodesToKeep.end(), cast2Node( nodeIt->next() ));
+ }
+
::SMESH_MeshEditor::TListOfListOfNodes aListOfListOfNodes;
- for (int i = 0; i < GroupsOfNodes.length(); i++)
+ for ( CORBA::ULong i = 0; i < GroupsOfNodes.length(); i++ )
{
const SMESH::long_array& aNodeGroup = GroupsOfNodes[ i ];
aListOfListOfNodes.push_back( list< const SMDS_MeshNode* >() );
list< const SMDS_MeshNode* >& aListOfNodes = aListOfListOfNodes.back();
- for ( int j = 0; j < aNodeGroup.length(); j++ )
+ for ( CORBA::ULong j = 0; j < aNodeGroup.length(); j++ )
{
CORBA::Long index = aNodeGroup[ j ];
- const SMDS_MeshNode * node = aMesh->FindNode(index);
- if ( node )
- aListOfNodes.push_back( node );
+ if ( const SMDS_MeshNode * node = aMesh->FindNode( index ))
+ {
+ if ( setOfNodesToKeep.count( node ))
+ aListOfNodes.push_front( node );
+ else
+ aListOfNodes.push_back( node );
+ }
}
if ( aListOfNodes.size() < 2 )
aListOfListOfNodes.pop_back();
if ( i > 0 ) aTPythonDump << ", ";
aTPythonDump << aNodeGroup;
}
- getEditor().MergeNodes( aListOfListOfNodes );
- aTPythonDump << "])";
+ getEditor().MergeNodes( aListOfListOfNodes, AvoidMakingHoles );
+
+ aTPythonDump << "], " << NodesToKeep << ", " << AvoidMakingHoles << ")";
declareMeshModified( /*isReComputeSafe=*/false );
::SMESH_MeshEditor::TListOfListOfElementsID aListOfListOfElementsID;
- for (int i = 0; i < GroupsOfElementsID.length(); i++) {
+ for ( CORBA::ULong i = 0; i < GroupsOfElementsID.length(); i++ ) {
const SMESH::long_array& anElemsIDGroup = GroupsOfElementsID[ i ];
aListOfListOfElementsID.push_back( list< int >() );
list< int >& aListOfElemsID = aListOfListOfElementsID.back();
- for ( int j = 0; j < anElemsIDGroup.length(); j++ ) {
+ for ( CORBA::ULong j = 0; j < anElemsIDGroup.length(); j++ ) {
CORBA::Long id = anElemsIDGroup[ j ];
aListOfElemsID.push_back( id );
}
SMDSAbs_ElementType( type ),
foundElems);
res->length( foundElems.size() );
- for ( int i = 0; i < foundElems.size(); ++i )
+ for ( size_t i = 0; i < foundElems.size(); ++i )
res[i] = foundElems[i]->GetID();
return res._retn();
{
SMESH_TRY;
SMESH::long_array_var res = new SMESH::long_array;
-
- SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
- if ( types->length() == 1 && // a part contains only nodes or 0D elements
- ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
- type != types[0] ) // but search of elements of dim > 0
- return res._retn();
+ if ( type != SMESH::NODE )
+ {
+ SMESH::array_of_ElementType_var types = elementIDs->GetTypes();
+ if ( types->length() == 1 && // a part contains only nodes or 0D elements
+ ( types[0] == SMESH::NODE || types[0] == SMESH::ELEM0D || types[0] == SMESH::BALL) &&
+ type != types[0] ) // but search of elements of dim > 0
+ return res._retn();
+ }
if ( SMESH::DownCast<SMESH_Mesh_i*>( elementIDs )) // elementIDs is the whole mesh
return FindElementsByPoint( x,y,z, type );
SMESHDS_Mesh* meshDS = SMESH::DownCast<SMESH_Mesh_i*>( mesh )->GetImpl().GetMeshDS();
if ( !idSourceToSet( elementIDs, meshDS, elements,
- SMDSAbs_ElementType(type), /*emptyIfIsMesh=*/true))
+ ( type == SMESH::NODE ? SMDSAbs_All : (SMDSAbs_ElementType) type ),
+ /*emptyIfIsMesh=*/true))
return res._retn();
typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
SMDSAbs_ElementType( type ),
foundElems);
res->length( foundElems.size() );
- for ( int i = 0; i < foundElems.size(); ++i )
+ for ( size_t i = 0; i < foundElems.size(); ++i )
res[i] = foundElems[i]->GetID();
return res._retn();
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() );
+ aSeq.swap( newFaces );
+
+ TPythonDump() << this << ".FillHole( SMESH.FreeBorder(" << theHole.nodeIDs << " ))";
+ }
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+}
+
//=======================================================================
//function : convError
//purpose :
RETCASE( SEW_TOPO_DIFF_SETS_OF_ELEMENTS );
RETCASE( SEW_BAD_SIDE1_NODES );
RETCASE( SEW_BAD_SIDE2_NODES );
+ RETCASE( SEW_INTERNAL_ERROR );
}
return SMESH::SMESH_MeshEditor::SEW_OK;
}
+//=======================================================================
+/*!
+ * Returns groups of FreeBorder's coincident within the given tolerance.
+ * If the tolerance <= 0.0 then one tenth of an average size of elements adjacent
+ * to free borders being compared is used.
+ */
+//=======================================================================
+
+SMESH::CoincidentFreeBorders*
+SMESH_MeshEditor_i::FindCoincidentFreeBorders(CORBA::Double tolerance)
+{
+ SMESH::CoincidentFreeBorders_var aCFB = new SMESH::CoincidentFreeBorders;
+
+ SMESH_TRY;
+
+ SMESH_MeshAlgos::CoincidentFreeBorders cfb;
+ SMESH_MeshAlgos::FindCoincidentFreeBorders( *getMeshDS(), tolerance, cfb );
+
+ // copy free borders
+ aCFB->borders.length( cfb._borders.size() );
+ for ( size_t i = 0; i < cfb._borders.size(); ++i )
+ {
+ SMESH_MeshAlgos::TFreeBorder& nodes = cfb._borders[i];
+ SMESH::FreeBorder& aBRD = aCFB->borders[i];
+ aBRD.nodeIDs.length( nodes.size() );
+ for ( size_t iN = 0; iN < nodes.size(); ++iN )
+ aBRD.nodeIDs[ iN ] = nodes[ iN ]->GetID();
+ }
+
+ // copy coincident parts
+ aCFB->coincidentGroups.length( cfb._coincidentGroups.size() );
+ for ( size_t i = 0; i < cfb._coincidentGroups.size(); ++i )
+ {
+ SMESH_MeshAlgos::TCoincidentGroup& grp = cfb._coincidentGroups[i];
+ SMESH::FreeBordersGroup& aGRP = aCFB->coincidentGroups[i];
+ aGRP.length( grp.size() );
+ for ( size_t iP = 0; iP < grp.size(); ++iP )
+ {
+ SMESH_MeshAlgos::TFreeBorderPart& part = grp[ iP ];
+ SMESH::FreeBorderPart& aPART = aGRP[ iP ];
+ aPART.border = part._border;
+ aPART.node1 = part._node1;
+ aPART.node2 = part._node2;
+ aPART.nodeLast = part._nodeLast;
+ }
+ }
+ SMESH_CATCH( SMESH::doNothing );
+
+ TPythonDump() << "CoincidentFreeBorders = "
+ << this << ".FindCoincidentFreeBorders( " << tolerance << " )";
+
+ return aCFB._retn();
+}
+
+//=======================================================================
+/*!
+ * Sew FreeBorder's of each group
+ */
+//=======================================================================
+
+CORBA::Short SMESH_MeshEditor_i::
+SewCoincidentFreeBorders(const SMESH::CoincidentFreeBorders& freeBorders,
+ CORBA::Boolean createPolygons,
+ CORBA::Boolean createPolyhedra)
+ throw (SALOME::SALOME_Exception)
+{
+ CORBA::Short nbSewed = 0;
+
+ SMESH_MeshAlgos::TFreeBorderVec groups;
+ SMESH_MeshAlgos::TFreeBorder borderNodes; // triples of nodes for every FreeBorderPart
+
+ // check the input and collect nodes
+ for ( CORBA::ULong i = 0; i < freeBorders.coincidentGroups.length(); ++i )
+ {
+ borderNodes.clear();
+ const SMESH::FreeBordersGroup& aGRP = freeBorders.coincidentGroups[ i ];
+ for ( CORBA::ULong iP = 0; iP < aGRP.length(); ++iP )
+ {
+ const SMESH::FreeBorderPart& aPART = aGRP[ iP ];
+ if ( aPART.border < 0 || aPART.border >= (int) freeBorders.borders.length() )
+ THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::border index", SALOME::BAD_PARAM);
+
+ const SMESH::FreeBorder& aBRD = freeBorders.borders[ aPART.border ];
+
+ if ( aPART.node1 < 0 || aPART.node1 > (int) aBRD.nodeIDs.length() )
+ THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node1", SALOME::BAD_PARAM);
+ if ( aPART.node2 < 0 || aPART.node2 > (int) aBRD.nodeIDs.length() )
+ THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::node2", SALOME::BAD_PARAM);
+ if ( aPART.nodeLast < 0 || aPART.nodeLast > (int) aBRD.nodeIDs.length() )
+ THROW_SALOME_CORBA_EXCEPTION("Invalid FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
+
+ // do not keep these nodes for further sewing as nodes can be removed by the sewing
+ const SMDS_MeshNode* n1 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node1 ]);
+ const SMDS_MeshNode* n2 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.node2 ]);
+ const SMDS_MeshNode* n3 = getMeshDS()->FindNode( aBRD.nodeIDs[ aPART.nodeLast ]);
+ if ( !n1)
+ THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node1", SALOME::BAD_PARAM);
+ if ( !n2 )
+ THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::node2", SALOME::BAD_PARAM);
+ if ( !n3 )
+ THROW_SALOME_CORBA_EXCEPTION("Nonexistent FreeBorderPart::nodeLast", SALOME::BAD_PARAM);
+
+ borderNodes.push_back( n1 );
+ borderNodes.push_back( n2 );
+ borderNodes.push_back( n3 );
+ }
+ groups.push_back( borderNodes );
+ }
+
+ // SewFreeBorder() can merge nodes, thus nodes stored in 'groups' can become dead;
+ // to get nodes that replace other nodes during merge we create 0D elements
+ // on each node and MergeNodes() will replace underlying nodes of 0D elements by
+ // new ones.
+
+ vector< const SMDS_MeshElement* > tmp0Delems;
+ for ( size_t i = 0; i < groups.size(); ++i )
+ {
+ SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
+ for ( size_t iN = 0; iN < nodes.size(); ++iN )
+ {
+ SMDS_ElemIteratorPtr it0D = nodes[iN]->GetInverseElementIterator(SMDSAbs_0DElement);
+ if ( it0D->more() )
+ tmp0Delems.push_back( it0D->next() );
+ else
+ tmp0Delems.push_back( getMeshDS()->Add0DElement( nodes[iN] ));
+ }
+ }
+
+ // cout << endl << "INIT" << endl;
+ // for ( size_t i = 0; i < tmp0Delems.size(); ++i )
+ // {
+ // cout << i << " ";
+ // if ( i % 3 == 0 ) cout << "^ ";
+ // tmp0Delems[i]->GetNode(0)->Print( cout );
+ // }
+
+ SMESH_TRY;
+
+ ::SMESH_MeshEditor::Sew_Error res, ok = ::SMESH_MeshEditor::SEW_OK;
+ int i0D = 0;
+ for ( size_t i = 0; i < groups.size(); ++i )
+ {
+ bool isBordToBord = true;
+ bool groupSewed = false;
+ SMESH_MeshAlgos::TFreeBorder& nodes = groups[i];
+ for ( size_t iN = 3; iN+2 < nodes.size(); iN += 3 )
+ {
+ const SMDS_MeshNode* n0 = tmp0Delems[ i0D + 0 ]->GetNode( 0 );
+ const SMDS_MeshNode* n1 = tmp0Delems[ i0D + 1 ]->GetNode( 0 );
+ const SMDS_MeshNode* n2 = tmp0Delems[ i0D + 2 ]->GetNode( 0 );
+
+ const SMDS_MeshNode* n3 = tmp0Delems[ i0D + 0 + iN ]->GetNode( 0 );
+ const SMDS_MeshNode* n4 = tmp0Delems[ i0D + 1 + iN ]->GetNode( 0 );
+ const SMDS_MeshNode* n5 = tmp0Delems[ i0D + 2 + iN ]->GetNode( 0 );
+
+ if ( !n0 || !n1 || !n2 || !n3 || !n4 || !n5 )
+ continue;
+
+ // TIDSortedElemSet emptySet, avoidSet;
+ // if ( !SMESH_MeshAlgos::FindFaceInSet( n0, n1, emptySet, avoidSet))
+ // {
+ // cout << "WRONG 2nd 1" << endl;
+ // n0->Print( cout );
+ // n1->Print( cout );
+ // }
+ // if ( !SMESH_MeshAlgos::FindFaceInSet( n3, n4, emptySet, avoidSet))
+ // {
+ // cout << "WRONG 2nd 2" << endl;
+ // n3->Print( cout );
+ // n4->Print( cout );
+ // }
+
+ if ( !isBordToBord )
+ {
+ n1 = n2; // at border-to-side sewing only last side node (n1) is needed
+ n2 = 0; // and n2 is not used
+ }
+ // 1st border moves to 2nd
+ res = getEditor().SewFreeBorder( n3, n4, n5 ,// 1st
+ n0 ,n1 ,n2 ,// 2nd
+ /*2ndIsFreeBorder=*/ isBordToBord,
+ createPolygons, createPolyhedra);
+ groupSewed = ( res == ok );
+
+ isBordToBord = false;
+ // cout << endl << "SEWED GROUP " << i << " PART " << iN / 3 << endl;
+ // for ( size_t t = 0; t < tmp0Delems.size(); ++t )
+ // {
+ // cout << t << " ";
+ // if ( t % 3 == 0 ) cout << "^ ";
+ // tmp0Delems[t]->GetNode(0)->Print( cout );
+ // }
+ }
+ i0D += nodes.size();
+ nbSewed += groupSewed;
+ }
+
+ TPythonDump() << "nbSewed = " << this << ".SewCoincidentFreeBorders( "
+ << freeBorders << ", "
+ << createPolygons << ", "
+ << createPolyhedra << " )";
+
+ SMESH_CATCH( SMESH::doNothing );
+
+ declareMeshModified( /*isReComputeSafe=*/false );
+
+ // remove tmp 0D elements
+ SMESH_TRY;
+ set< const SMDS_MeshElement* > removed0D;
+ for ( size_t i = 0; i < tmp0Delems.size(); ++i )
+ {
+ if ( removed0D.insert( tmp0Delems[i] ).second )
+ getMeshDS()->RemoveFreeElement( tmp0Delems[i], /*sm=*/0, /*fromGroups=*/false );
+ }
+ SMESH_CATCH( SMESH::throwCorbaException );
+
+ return nbSewed;
+}
+
//=======================================================================
//function : SewFreeBorders
//purpose :
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( getEditor().SewFreeBorder (aBorderFirstNode,
- aBorderSecondNode,
- aBorderLastNode,
- aSide2FirstNode,
- aSide2SecondNode,
- aSide2ThirdNode,
- true,
- CreatePolygons,
- CreatePolyedrs) );
+ aBorderSecondNode,
+ aBorderLastNode,
+ aSide2FirstNode,
+ aSide2SecondNode,
+ aSide2ThirdNode,
+ true,
+ CreatePolygons,
+ CreatePolyedrs) );
declareMeshModified( /*isReComputeSafe=*/false );
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( getEditor().SewFreeBorder (aBorderFirstNode,
- aBorderSecondNode,
- aBorderLastNode,
- aSide2FirstNode,
- aSide2SecondNode,
- aSide2ThirdNode,
- true,
- false, false) );
+ aBorderSecondNode,
+ aBorderLastNode,
+ aSide2FirstNode,
+ aSide2SecondNode,
+ aSide2ThirdNode,
+ true,
+ false, false) );
declareMeshModified( /*isReComputeSafe=*/false );
return error;
SMESH::SMESH_MeshEditor::Sew_Error error =
convError( getEditor().SewFreeBorder (aBorderFirstNode,
- aBorderSecondNode,
- aBorderLastNode,
- aSide2FirstNode,
- aSide2SecondNode,
- aSide2ThirdNode,
- false,
- CreatePolygons,
- CreatePolyedrs) );
+ aBorderSecondNode,
+ aBorderLastNode,
+ aSide2FirstNode,
+ aSide2SecondNode,
+ aSide2ThirdNode,
+ false,
+ CreatePolygons,
+ CreatePolyedrs) );
declareMeshModified( /*isReComputeSafe=*/false );
return error;
TPythonDump() << "isDone = " << this << ".ChangeElemNodes( "
<< ide << ", " << newIDs << " )";
- MESSAGE("ChangeElementNodes");
bool res = getMeshDS()->ChangeElementNodes( elem, & aNodes[0], nbn1+1 );
declareMeshModified( /*isReComputeSafe=*/ !res );
*/
//================================================================================
-string SMESH_MeshEditor_i::generateGroupName(const string& thePrefix)
+std::string SMESH_MeshEditor_i::generateGroupName(const std::string& thePrefix)
{
SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
- set<string> groupNames;
+ set<std::string> groupNames;
// Get existing group names
for (int i = 0, nbGroups = groups->length(); i < nbGroups; i++ ) {
}
// Find new name
- string name = thePrefix;
+ std::string name = thePrefix;
int index = 0;
while (!groupNames.insert(name).second)
{
if ( error ) *error = IDSource_OK;
- if ( CORBA::is_nil( theIDSource ) )
+ if ( CORBA::is_nil( theIDSource ))
{
if ( error ) *error = IDSource_INVALID;
return false;
* \param theElements - container of elements to duplicate.
* \param theGroupName - a name of group to contain the generated elements.
* If a group with such a name already exists, the new elements
- * are added to the existng group, else a new group is created.
+ * are added to the existing group, else a new group is created.
* If \a theGroupName is empty, new elements are not added
* in any group.
* \return a group where the new elements are added. NULL if theGroupName == "".
{
getEditor().DoubleElements( elems );
- if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().IsEmpty() )
+ if ( strlen( theGroupName ) && !getEditor().GetLastCreatedElems().empty() )
{
// group type
SMESH::ElementType type =
- SMESH::ElementType( getEditor().GetLastCreatedElems().Value(1)->GetType() );
+ SMESH::ElementType( getEditor().GetLastCreatedElems()[0]->GetType() );
// find existing group
SMESH::ListOfGroups_var groups = myMesh_i->GetGroups();
for ( size_t i = 0; i < groups->length(); ++i )
{
SMESHDS_Group* groupDS = static_cast< SMESHDS_Group* >( group_i->GetGroupDS() );
const SMESH_SequenceOfElemPtr& aSeq = getEditor().GetLastCreatedElems();
- for ( int i = 1; i <= aSeq.Length(); i++ )
- groupDS->SMDSGroup().Add( aSeq(i) );
+ for ( size_t i = 0; i <= aSeq.size(); i++ )
+ groupDS->SMDSGroup().Add( aSeq[i] );
}
}
}
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
// Create group with newly created nodes
SMESH::long_array_var anIds = GetLastCreatedNodes();
if (anIds->length() > 0) {
- string anUnindexedName (theNodes->GetName());
- string aNewName = generateGroupName(anUnindexedName + "_double");
+ std::string anUnindexedName (theNodes->GetName());
+ std::string aNewName = generateGroupName(anUnindexedName + "_double");
aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
aNewGroup->Add(anIds);
pyDump << aNewGroup << " = ";
// Create group with newly created nodes
SMESH::long_array_var anIds = GetLastCreatedNodes();
if (anIds->length() > 0) {
- string anUnindexedName (theNodes[0]->GetName());
- string aNewName = generateGroupName(anUnindexedName + "_double");
+ std::string anUnindexedName (theNodes[0]->GetName());
+ std::string aNewName = generateGroupName(anUnindexedName + "_double");
aNewGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
aNewGroup->Add(anIds);
pyDump << aNewGroup << " = ";
{
// Create group with newly created elements
CORBA::String_var elemGroupName = theElems->GetName();
- string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
- if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+ std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
+ if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedElems();
SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
aNewElemGroup->Add(anIds);
}
- if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+ if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedNodes();
aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
{
// Create group with newly created elements
CORBA::String_var elemGroupName = theElems[0]->GetName();
- string aNewName = generateGroupName( string(elemGroupName.in()) + "_double");
- if ( !getEditor().GetLastCreatedElems().IsEmpty() && theElemGroupNeeded )
+ std::string aNewName = generateGroupName( std::string(elemGroupName.in()) + "_double");
+ if ( !getEditor().GetLastCreatedElems().empty() && theElemGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedElems();
SMESH::ElementType aGroupType = myMesh_i->GetElementType(anIds[0], true);
aNewElemGroup = myMesh_i->CreateGroup(aGroupType, aNewName.c_str());
aNewElemGroup->Add(anIds);
}
- if ( !getEditor().GetLastCreatedNodes().IsEmpty() && theNodeGroupNeeded )
+ if ( !getEditor().GetLastCreatedNodes().empty() && theNodeGroupNeeded )
{
SMESH::long_array_var anIds = GetLastCreatedNodes();
aNewNodeGroup = myMesh_i->CreateGroup(SMESH::NODE, aNewName.c_str());
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
*/
//================================================================================
theNodeSearcher = SMESH_MeshAlgos::GetNodeSearcher( *getMeshDS() );
vector<double> nodesCoords;
- for (int i = 0; i < theNodesCoords.length(); i++)
+ for ( CORBA::ULong i = 0; i < theNodesCoords.length(); i++)
{
nodesCoords.push_back( theNodesCoords[i] );
}
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( "
THROW_SALOME_CORBA_EXCEPTION("Invalid boundary dimension", SALOME::BAD_PARAM);
// separate groups belonging to this and other mesh
- SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
+ SMESH::ListOfIDSources_var groupsOfThisMesh = new SMESH::ListOfIDSources;
SMESH::ListOfIDSources_var groupsOfOtherMesh = new SMESH::ListOfIDSources;
- groupsOfThisMesh->length( groups.length() );
+ groupsOfThisMesh ->length( groups.length() );
groupsOfOtherMesh->length( groups.length() );
int nbGroups = 0, nbGroupsOfOtherMesh = 0;
- for ( int i = 0; i < groups.length(); ++i )
+ for ( CORBA::ULong i = 0; i < groups.length(); ++i )
{
SMESH::SMESH_Mesh_var m = groups[i]->GetMesh();
if ( myMesh_i != SMESH::DownCast<SMESH_Mesh_i*>( m ))
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;
+}