#include "SMESH_MeshEditor.hxx"
-#include "SMDS_FaceOfNodes.hxx"
-#include "SMDS_VolumeTool.hxx"
+#include "SMDS_Downward.hxx"
#include "SMDS_EdgePosition.hxx"
+#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_FacePosition.hxx"
-#include "SMDS_SpacePosition.hxx"
-#include "SMDS_MeshGroup.hxx"
#include "SMDS_LinearEdge.hxx"
-#include "SMDS_Downward.hxx"
+#include "SMDS_MeshGroup.hxx"
#include "SMDS_SetIterator.hxx"
-
+#include "SMDS_SpacePosition.hxx"
+#include "SMDS_VolumeTool.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
-
#include "SMESH_Algo.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMESH_Group.hxx"
+#include "SMESH_Mesh.hxx"
#include "SMESH_MeshAlgos.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_OctreeNode.hxx"
#include <TopTools_ListOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Solid.hxx>
#include <gp.hxx>
{
}
+//================================================================================
+/*!
+ * \brief Return mesh DS
+ */
+//================================================================================
+
+SMESHDS_Mesh * SMESH_MeshEditor::GetMeshDS()
+{
+ return myMesh->GetMeshDS();
+}
+
+
//================================================================================
/*!
* \brief Clears myLastCreatedNodes and myLastCreatedElems
//================================================================================
/*!
- * \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 elements - Elements on whose nodes to create 0D elements; if empty,
* the all mesh is treated
* \param all0DElems - returns all 0D elements found or created on nodes of \a elements
+ * \param duplicateElements - to add one more 0D element to a node or not
*/
//================================================================================
void SMESH_MeshEditor::Create0DElementsOnAllNodes( const TIDSortedElemSet& elements,
- TIDSortedElemSet& all0DElems )
+ TIDSortedElemSet& all0DElems,
+ const bool duplicateElements )
{
SMDS_ElemIteratorPtr elemIt;
- vector< const SMDS_MeshElement* > allNodes;
if ( elements.empty() )
{
- allNodes.reserve( GetMeshDS()->NbNodes() );
elemIt = GetMeshDS()->elementsIterator( SMDSAbs_Node );
- while ( elemIt->more() )
- allNodes.push_back( elemIt->next() );
-
- elemIt = elemSetIterator( allNodes );
}
else
{
{
const SMDS_MeshNode* n = cast2Node( nodeIt->next() );
SMDS_ElemIteratorPtr it0D = n->GetInverseElementIterator( SMDSAbs_0DElement );
- if ( it0D->more() )
- all0DElems.insert( it0D->next() );
- else {
+ if ( duplicateElements || !it0D->more() )
+ {
myLastCreatedElems.Append( GetMeshDS()->Add0DElement( n ));
all0DElems.insert( myLastCreatedElems.Last() );
}
+ while ( it0D->more() )
+ all0DElems.insert( it0D->next() );
}
}
}
fToler2 = BRep_Tool::Tolerance( face );
fToler2 *= fToler2 * 10.;
isUPeriodic = surface->IsUPeriodic();
- if ( isUPeriodic )
- surface->UPeriod();
+ // if ( isUPeriodic )
+ // surface->UPeriod();
isVPeriodic = surface->IsVPeriodic();
- if ( isVPeriodic )
- surface->VPeriod();
+ // if ( isVPeriodic )
+ // surface->VPeriod();
surface->Bounds( u1, u2, v1, v2 );
helper.SetSubShape( face );
}
{
// check if all faces around the node are on faceSubMesh
// because a node on edge may be bound to face
- SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
bool all = true;
if ( faceSubMesh ) {
+ SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator(SMDSAbs_Face);
while ( eIt->more() && all ) {
const SMDS_MeshElement* e = eIt->next();
all = faceSubMesh->Contains( e );
//purpose : standard construction
//=======================================================================
-SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
- const int theNbSteps,
- const int theFlags,
- const double theTolerance):
+SMESH_MeshEditor::ExtrusParam::ExtrusParam( const gp_Vec& theStep,
+ const int theNbSteps,
+ const std::list<double>& theScales,
+ const gp_XYZ* theBasePoint,
+ const int theFlags,
+ const double theTolerance):
myDir( theStep ),
+ myBaseP( Precision::Infinite(), 0, 0 ),
myFlags( theFlags ),
myTolerance( theTolerance ),
myElemsToUse( NULL )
for (int i=1; i<=theNbSteps; i++ )
mySteps->Append( stepSize );
+ int nbScales = theScales.size();
+ if ( nbScales > 0 )
+ {
+ if ( IsLinearVariation() && nbScales < theNbSteps )
+ {
+ myScales.reserve( theNbSteps );
+ std::list<double>::const_iterator scale = theScales.begin();
+ double prevScale = 1.0;
+ for ( int iSc = 1; scale != theScales.end(); ++scale, ++iSc )
+ {
+ int iStep = int( iSc / double( nbScales ) * theNbSteps + 0.5 );
+ int stDelta = Max( 1, iStep - myScales.size());
+ double scDelta = ( *scale - prevScale ) / stDelta;
+ for ( int iStep = 0; iStep < stDelta; ++iStep )
+ {
+ myScales.push_back( prevScale + scDelta );
+ prevScale = myScales.back();
+ }
+ prevScale = *scale;
+ }
+ }
+ else
+ {
+ myScales.assign( theScales.begin(), theScales.end() );
+ }
+ }
+ if ( theBasePoint )
+ {
+ myBaseP = *theBasePoint;
+ }
+
if (( theFlags & EXTRUSION_FLAG_SEW ) &&
( theTolerance > 0 ))
{
//=======================================================================
//function : ExtrusParam::SetElementsToUse
//purpose : stores elements to use for extrusion by normal, depending on
-// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag
+// state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag;
+// define myBaseP for scaling
//=======================================================================
-void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems )
+void SMESH_MeshEditor::ExtrusParam::SetElementsToUse( const TIDSortedElemSet& elems,
+ const TIDSortedElemSet& nodes )
{
myElemsToUse = ToUseInpElemsOnly() ? & elems : 0;
+
+ if ( Precision::IsInfinite( myBaseP.X() )) // myBaseP not defined
+ {
+ myBaseP.SetCoord( 0.,0.,0. );
+ TIDSortedElemSet newNodes;
+
+ const TIDSortedElemSet* elemSets[] = { &elems, &nodes };
+ for ( int is2ndSet = 0; is2ndSet < 2; ++is2ndSet )
+ {
+ const TIDSortedElemSet& elements = *( elemSets[ is2ndSet ]);
+ TIDSortedElemSet::const_iterator itElem = elements.begin();
+ for ( ; itElem != elements.end(); itElem++ )
+ {
+ const SMDS_MeshElement* elem = *itElem;
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ const SMDS_MeshElement* node = itN->next();
+ if ( newNodes.insert( node ).second )
+ myBaseP += SMESH_TNodeXYZ( node );
+ }
+ }
+ }
+ myBaseP /= newNodes.size();
+ }
}
//=======================================================================
const SMDS_MeshNode * newNode = mesh->AddNode( p.X(), p.Y(), p.Z() );
newNodes.push_back( newNode );
}
+
+ if ( !myScales.empty() )
+ {
+ if ( makeMediumNodes && myMediumScales.empty() )
+ {
+ myMediumScales.resize( myScales.size() );
+ double prevFactor = 1.;
+ for ( size_t i = 0; i < myScales.size(); ++i )
+ {
+ myMediumScales[i] = 0.5 * ( prevFactor + myScales[i] );
+ prevFactor = myScales[i];
+ }
+ }
+ typedef std::vector<double>::iterator ScaleIt;
+ ScaleIt scales[] = { myScales.begin(), myMediumScales.begin() };
+
+ size_t iSc = 0, nbScales = myScales.size() + myMediumScales.size();
+
+ gp_XYZ center = myBaseP;
+ std::list<const SMDS_MeshNode*>::iterator nIt = newNodes.begin();
+ size_t iN = 0;
+ for ( beginStepIter( makeMediumNodes ); moreSteps() && ( iN < nbScales ); ++nIt, ++iN )
+ {
+ center += myDir.XYZ() * nextStep();
+
+ iSc += int( makeMediumNodes );
+ ScaleIt& scale = scales[ iSc % 2 ];
+
+ gp_XYZ xyz = SMESH_TNodeXYZ( *nIt );
+ xyz = ( *scale * ( xyz - center )) + center;
+ mesh->MoveNode( *nIt, xyz.X(), xyz.Y(), xyz.Z() );
+
+ ++scale;
+ }
+ }
return nbNodes;
}
const int theFlags,
const double theTolerance)
{
- ExtrusParam aParams( theStep, theNbSteps, theFlags, theTolerance );
+ ExtrusParam aParams( theStep, theNbSteps, std::list<double>(), 0, theFlags, theTolerance );
return ExtrusionSweep( theElems, aParams, newElemsMap );
}
// source elements for each generated one
SMESH_SequenceOfElemPtr srcElems, srcNodes;
- //SMESHDS_Mesh* aMesh = GetMeshDS();
-
setElemsFirst( theElemSets );
const int nbSteps = theParams.NbSteps();
- theParams.SetElementsToUse( theElemSets[0] );
+ theParams.SetElementsToUse( theElemSets[0], theElemSets[1] );
- TNodeOfNodeListMap mapNewNodes;
- //TNodeOfNodeVecMap mapNewNodes;
+ TNodeOfNodeListMap mapNewNodes;
TElemOfVecOfNnlmiMap mapElemNewNodes;
- //TElemOfVecOfMapNodesMap mapElemNewNodes;
const bool isQuadraticMesh = bool( myMesh->NbEdges(ORDER_QUADRATIC) +
myMesh->NbFaces(ORDER_QUADRATIC) +
//=======================================================================
//function : LinearAngleVariation
-//purpose : auxilary for ExtrusionAlongTrack
+//purpose : spread values over nbSteps
//=======================================================================
-void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
+
+void SMESH_MeshEditor::LinearAngleVariation(const int nbSteps,
list<double>& Angles)
{
int nbAngles = Angles.size();
- if( nbSteps > nbAngles ) {
+ if( nbSteps > nbAngles && nbAngles > 0 )
+ {
vector<double> theAngles(nbAngles);
- list<double>::iterator it = Angles.begin();
- int i = -1;
- for(; it!=Angles.end(); it++) {
- i++;
- theAngles[i] = (*it);
- }
+ theAngles.assign( Angles.begin(), Angles.end() );
+
list<double> res;
double rAn2St = double( nbAngles ) / double( nbSteps );
double angPrev = 0, angle;
- for ( int iSt = 0; iSt < nbSteps; ++iSt ) {
+ for ( int iSt = 0; iSt < nbSteps; ++iSt )
+ {
double angCur = rAn2St * ( iSt+1 );
double angCurFloor = floor( angCur );
double angPrevFloor = floor( angPrev );
res.push_back(angle);
angPrev = angCur;
}
- Angles.clear();
- it = res.begin();
- for(; it!=res.end(); it++)
- Angles.push_back( *it );
+ Angles.swap( res );
}
}