-This is the version 2.2.0 of SMESH
+This is the version 3.0.0 of SMESH
Compatible with :
- - KERNEL 2.2.0
- - GEOM 2.2.0
- - MED 2.2.0
+ - KERNEL 3.0.0
+ - GUI 3.0.0
+ - GEOM 3.0.0
+ - MED 3.0.0
mesh_move_node.png \
mesh_orientation.png \
mesh.png \
+mesh_polygon.png \
+mesh_polyhedron.png \
mesh_pyramid_n.png \
mesh_pyramid.png \
mesh_quad_n.png \
MOC = @MOC@
UIC = @UIC@
-
+MSG2QM = @MSG2QM@
#QWT
$(SWIG) $(SWIG_FLAGS) -o $@ $<
$(top_builddir)/share/salome/resources/%.qm: %.po
- if test -e ${KERNEL_ROOT_DIR}/bin/salome/msg2qm ; then \
- ${KERNEL_ROOT_DIR}/bin/salome/msg2qm $< $@ ; \
- else \
- $(top_builddir)/bin/salome/msg2qm $< $@ ; \
- fi
+ $(MSG2QM) $< $@ ; \
#------------------------------------------------------------------------------
# The following section of this makefile contains dependencies between the
-THIS IS SALOME - SMESH VERSION: 2.2.0
+THIS IS SALOME - SMESH VERSION: 3.0.0
echo
echo ---------------------------------------------
+echo testing MSG2QM
+echo ---------------------------------------------
+echo
+
+CHECK_MSG2QM
+
+echo
+echo ---------------------------------------------
echo testing VTK
echo ---------------------------------------------
echo
/*!
* Filter
*/
- interface Filter: SALOME::GenericObj
+ interface Filter: SALOME::GenericObj, SMESH_IDSource
{
/*!
* Structure containing information about one criterion
typedef sequence<Criterion> Criteria;
void SetPredicate( in Predicate thePredicate );
+ void SetMesh( in SMESH_Mesh theMesh );
+
long_array GetElementsId( in SMESH_Mesh theMesh );
ElementType GetElementType();
Predicate GetPredicate();
module SMESH
{
+ interface Predicate;
+
/*!
* SMESH_Group: base interface of group object
*/
* Adds elements to the group
*/
long Add( in long_array elem_ids );
+ long AddByPredicate( in Predicate thePredicate );
/*!
* Removes elements from the group
*/
long Remove( in long_array elem_ids );
+ long RemoveByPredicate( in Predicate thePredicate );
};
/*!
ADD_EDGE,
ADD_TRIANGLE,
ADD_QUADRANGLE,
+ ADD_POLYGON,
ADD_TETRAHEDRON,
ADD_PYRAMID,
ADD_PRISM,
ADD_HEXAHEDRON,
+ ADD_POLYHEDRON,
REMOVE_NODE,
REMOVE_ELEMENT,
MOVE_NODE,
CHANGE_ELEMENT_NODES,
+ CHANGE_POLYHEDRON_NODES,
RENUMBER
};
long NbQuadrangles()
raises (SALOME::SALOME_Exception);
+ long NbPolygons()
+ raises (SALOME::SALOME_Exception);
+
long NbVolumes()
raises (SALOME::SALOME_Exception);
long NbPrisms()
raises (SALOME::SALOME_Exception);
+ long NbPolyhedrons()
+ raises (SALOME::SALOME_Exception);
+
long NbSubMesh()
raises (SALOME::SALOME_Exception);
raises (SALOME::SALOME_Exception);
};
- /*
+ /*!
* This interface makes modifications on the Mesh - removing elements and nodes etc.
*/
interface NumericalFunctor;
boolean AddVolume(in long_array IDsOfNodes);
+ //boolean AddPolygonalFace (in long_array IdsOfNodes);
+
+ /*!
+ * Create volume of many faces, giving nodes for each face.
+ * \param IdsOfNodes List of node IDs for volume creation face by face.
+ * \param Quantities List of integer values, Quantities[i]
+ * gives quantity of nodes in face number i.
+ */
+ boolean AddPolyhedralVolume (in long_array IdsOfNodes,
+ in long_array Quantities);
+
+ /*!
+ * Create volume of many faces, giving IDs of existing faces.
+ * \param IdsOfFaces List of face IDs for volume creation.
+ * \note The created volume will refer only to nodes
+ * of the given faces, not to the faces itself.
+ */
+ boolean AddPolyhedralVolumeByFaces (in long_array IdsOfFaces);
+
boolean MoveNode(in long NodeID, in double x, in double y, in double z);
boolean InverseDiag(in long NodeID1, in long NodeID2);
in double MaxAspectRatio,
in Smooth_Method Method);
+ boolean SmoothParametric(in long_array IDsOfElements,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
+ boolean SmoothParametricObject(in SMESH_IDSource theObject,
+ in long_array IDsOfFixedNodes,
+ in long MaxNbOfIterations,
+ in double MaxAspectRatio,
+ in Smooth_Method Method);
+
void RenumberNodes();
void RenumberElements();
in long LastNodeID1,
in long FirstNodeID2,
in long SecondNodeID2,
- in long LastNodeID2);
+ in long LastNodeID2,
+ in boolean CreatePolygons,
+ in boolean CreatePolyedrs);
Sew_Error SewConformFreeBorders (in long FirstNodeID1,
in long SecondNodeID1,
in long SecondNodeIDOnFreeBorder,
in long LastNodeIDOnFreeBorder,
in long FirstNodeIDOnSide,
- in long LastNodeIDOnSide);
+ in long LastNodeIDOnSide,
+ in boolean CreatePolygons,
+ in boolean CreatePolyedrs);
Sew_Error SewSideElements (in long_array IDsOfSide1Elements,
in long_array IDsOfSide2Elements,
/*!
* Create nodes and elements in <theMesh> using nodes
- * coordinates computed by either of Apply...() methods
+ * coordinates computed by either of Apply...() methods.
+ * If CreatePolygons is TRUE, replace adjacent faces by polygons
+ * to keep mesh conformity.
+ * If CreatePolyedrs is TRUE, replace adjacent volumes by polyedrs
+ * to keep mesh conformity.
*/
- boolean MakeMesh(in SMESH_Mesh theMesh);
+ boolean MakeMesh (in SMESH_Mesh theMesh,
+ in boolean CreatePolygons,
+ in boolean CreatePolyedrs);
/*!
* Return the loaded pattern in the string form to be saved in file
<component-username>Mesh</component-username>
<component-type>MESH</component-type>
<component-author>NRI</component-author>
- <component-version>2.2.0</component-version>
+ <component-version>3.0.0</component-version>
<component-comment>Mesh component</component-comment>
<component-multistudy>1</component-multistudy>
<component-icone>ModuleMesh.png</component-icone>
<popup-item item-id="401" pos-id="" label-id="Edge" icon-id="mesh_line.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="4021" pos-id="" label-id="Triangle" icon-id="mesh_triangle.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="4022" pos-id="" label-id="Quadrangle" icon-id="mesh_quad.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="4023" pos-id="" label-id="Polygon" icon-id="mesh_polygon.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="4031" pos-id="" label-id="Tetrahedron" icon-id="mesh_tetra.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
<popup-item item-id="4032" pos-id="" label-id="Hexahedron" icon-id="mesh_hexa.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
+ <popup-item item-id="4033" pos-id="" label-id="Polyhedron" icon-id="mesh_polyhedron.png" tooltip-id="" accel-id="" toggle-id="" execute-action=""/>
</submenu>
<endsubmenu />
<submenu label-id="Remove" item-id="403" pos-id="">
<toolbutton-item item-id="401" label-id="Edge" icon-id="mesh_line.png" tooltip-id="Add Edge" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="4021" label-id="Triangle" icon-id="mesh_triangle.png" tooltip-id="Add Triangle" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="4022" label-id="Quadrangle" icon-id="mesh_quad.png" tooltip-id="Add Quadrangle" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="4023" label-id="Polygon" icon-id="mesh_polygon.png" tooltip-id="Add Polygon" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="4031" label-id="Tetrahedron" icon-id="mesh_tetra.png" tooltip-id="Add Tetrahedron" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="4032" label-id="Hexahedron" icon-id="mesh_hexa.png" tooltip-id="Add Hexahedron" accel-id="" toggle-id="" execute-action=""/>
+ <toolbutton-item item-id="4033" label-id="Polyhedron" icon-id="mesh_polyhedron.png" tooltip-id="Add Polyhedron" accel-id="" toggle-id="" execute-action=""/>
<separatorTB/>
<toolbutton-item item-id="4041" label-id="Nodes" icon-id="mesh_rem_node.png" tooltip-id="Remove Nodes" accel-id="" toggle-id="" execute-action=""/>
<toolbutton-item item-id="4042" label-id="Elements" icon-id="mesh_rem_element.png" tooltip-id="Remove Elements" accel-id="" toggle-id="" execute-action=""/>
return aDist;
}
- int getNbMultiConnection( SMDS_Mesh* theMesh, const int theId )
+ int getNbMultiConnection( const SMDS_Mesh* theMesh, const int theId )
{
if ( theMesh == 0 )
return 0;
myPrecision = -1;
}
-void NumericalFunctor::SetMesh( SMDS_Mesh* theMesh )
+void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
}
{
double aMin;
- if ( P.size() == 3 )
- {
- double A0 = getAngle( P( 3 ), P( 1 ), P( 2 ) );
- double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
- double A2 = getAngle( P( 2 ), P( 3 ), P( 1 ) );
-
- aMin = Min( A0, Min( A1, A2 ) );
- }
- else if ( P.size() == 4 )
- {
- double A0 = getAngle( P( 4 ), P( 1 ), P( 2 ) );
- double A1 = getAngle( P( 1 ), P( 2 ), P( 3 ) );
- double A2 = getAngle( P( 2 ), P( 3 ), P( 4 ) );
- double A3 = getAngle( P( 3 ), P( 4 ), P( 1 ) );
-
- aMin = Min( Min( A0, A1 ), Min( A2, A3 ) );
- }
- else
+ if (P.size() <3)
return 0.;
+
+ aMin = getAngle(P( P.size() ), P( 1 ), P( 2 ));
+ aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 )));
+ for (int i=2; i<P.size();i++){
+ double A0 = getAngle( P( i-1 ), P( i ), P( i+1 ) );
+ aMin = Min(aMin,A0);
+ }
+
return aMin * 180 / PI;
}
gp_Vec aVec2( P( 3 ) - P( 1 ) );
gp_Vec aVec3( P( 4 ) - P( 1 ) );
gp_Vec anAreaVec( aVec1 ^ aVec2 );
- return abs(aVec3 * anAreaVec) / 6.0;
+ return fabs(aVec3 * anAreaVec) / 6.0;
}
inline double getMaxHeight(double theLen[6])
if ( L < Precision::Confusion())
return 0.;
- gp_XYZ GI = ( thePnt2 - thePnt1 ) / 2. - theG;
- gp_XYZ GJ = ( thePnt3 - thePnt2 ) / 2. - theG;
+ gp_XYZ GI = ( thePnt2 + thePnt1 ) / 2. - theG;
+ gp_XYZ GJ = ( thePnt3 + thePnt2 ) / 2. - theG;
gp_XYZ N = GI.Crossed( GJ );
if ( N.Modulus() < gp::Resolution() )
*/
double Area::GetValue( const TSequenceOfXYZ& P )
{
+ double aArea = 0;
if ( P.size() == 3 )
return getArea( P( 1 ), P( 2 ), P( 3 ) );
- else if ( P.size() == 4 )
- return getArea( P( 1 ), P( 2 ), P( 3 ) ) + getArea( P( 1 ), P( 3 ), P( 4 ) );
+ else if (P.size() > 3)
+ aArea = getArea( P( 1 ), P( 2 ), P( 3 ) );
else
return 0;
+
+ for (int i=4; i<=P.size(); i++)
+ aArea += getArea(P(1),P(i-1),P(i));
+ return aArea;
}
double Area::GetBadRate( double Value, int /*nbNodes*/ ) const
int aResult = 0;
if (GetPoints(theElementId,P)){
- double aVal;
const SMDS_MeshElement* anFaceElem = myMesh->FindElement( theElementId );
SMDSAbs_ElementType aType = anFaceElem->GetType();
SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
for(; anIter->more(); ){
const SMDS_MeshFace* anElem = anIter->next();
- long anElemId = anElem->GetID();
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
long aNodeId[3];
myMesh = 0;
}
-void BadOrientedVolume::SetMesh( SMDS_Mesh* theMesh )
+void BadOrientedVolume::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
}
myMesh = 0;
}
-void FreeBorders::SetMesh( SMDS_Mesh* theMesh )
+void FreeBorders::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
}
myMesh = 0;
}
-void FreeEdges::SetMesh( SMDS_Mesh* theMesh )
+void FreeEdges::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
}
// name : SetMesh
// Purpose : Set mesh
//=======================================================================
-void RangeOfIds::SetMesh( SMDS_Mesh* theMesh )
+void RangeOfIds::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
}
Comparator::~Comparator()
{}
-void Comparator::SetMesh( SMDS_Mesh* theMesh )
+void Comparator::SetMesh( const SMDS_Mesh* theMesh )
{
if ( myFunctor )
myFunctor->SetMesh( theMesh );
return myPredicate && !myPredicate->IsSatisfy( theId );
}
-void LogicalNOT::SetMesh( SMDS_Mesh* theMesh )
+void LogicalNOT::SetMesh( const SMDS_Mesh* theMesh )
{
if ( myPredicate )
myPredicate->SetMesh( theMesh );
LogicalBinary::~LogicalBinary()
{}
-void LogicalBinary::SetMesh( SMDS_Mesh* theMesh )
+void LogicalBinary::SetMesh( const SMDS_Mesh* theMesh )
{
if ( myPredicate1 )
myPredicate1->SetMesh( theMesh );
myPredicate = thePredicate;
}
-
template<class TElement, class TIterator, class TPredicate>
-void FillSequence(const TIterator& theIterator,
- TPredicate& thePredicate,
- Filter::TIdSequence& theSequence)
+inline void FillSequence(const TIterator& theIterator,
+ TPredicate& thePredicate,
+ Filter::TIdSequence& theSequence)
{
if ( theIterator ) {
while( theIterator->more() ) {
}
}
-Filter::TIdSequence
-Filter::GetElementsId( SMDS_Mesh* theMesh )
+void
+Filter::
+GetElementsId( const SMDS_Mesh* theMesh,
+ PredicatePtr thePredicate,
+ TIdSequence& theSequence )
{
- TIdSequence aSequence;
- if ( !theMesh || !myPredicate ) return aSequence;
+ theSequence.clear();
+
+ if ( !theMesh || !thePredicate )
+ return;
- myPredicate->SetMesh( theMesh );
+ thePredicate->SetMesh( theMesh );
- SMDSAbs_ElementType aType = myPredicate->GetType();
+ SMDSAbs_ElementType aType = thePredicate->GetType();
switch(aType){
- case SMDSAbs_Node:{
- FillSequence<const SMDS_MeshNode*>(theMesh->nodesIterator(),myPredicate,aSequence);
+ case SMDSAbs_Node:
+ FillSequence<const SMDS_MeshNode*>(theMesh->nodesIterator(),thePredicate,theSequence);
break;
- }
- case SMDSAbs_Edge:{
- FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),myPredicate,aSequence);
+ case SMDSAbs_Edge:
+ FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
break;
- }
- case SMDSAbs_Face:{
- FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),myPredicate,aSequence);
+ case SMDSAbs_Face:
+ FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
break;
- }
- case SMDSAbs_Volume:{
- FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),myPredicate,aSequence);
+ case SMDSAbs_Volume:
+ FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
break;
- }
- case SMDSAbs_All:{
- FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),myPredicate,aSequence);
- FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),myPredicate,aSequence);
- FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),myPredicate,aSequence);
+ case SMDSAbs_All:
+ FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
+ FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
+ FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
break;
}
- }
- return aSequence;
+}
+
+void
+Filter::GetElementsId( const SMDS_Mesh* theMesh,
+ Filter::TIdSequence& theSequence )
+{
+ GetElementsId(theMesh,myPredicate,theSequence);
}
/*
myMesh = 0;
}
-void ManifoldPart::SetMesh( SMDS_Mesh* theMesh )
+void ManifoldPart::SetMesh( const SMDS_Mesh* theMesh )
{
myMesh = theMesh;
process();
myMesh = 0;
}
-void ElementsOnSurface::SetMesh( SMDS_Mesh* theMesh )
+void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh )
{
if ( myMesh == theMesh )
return;
{
public:
~Functor(){}
- virtual void SetMesh( SMDS_Mesh* theMesh ) = 0;
+ virtual void SetMesh( const SMDS_Mesh* theMesh ) = 0;
virtual SMDSAbs_ElementType GetType() const = 0;
};
class NumericalFunctor: public virtual Functor{
public:
NumericalFunctor();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual double GetValue( long theElementId );
virtual double GetValue(const TSequenceOfXYZ& thePoints) { return -1.0;};
virtual SMDSAbs_ElementType GetType() const = 0;
static bool GetPoints(const SMDS_MeshElement* theElem,
TSequenceOfXYZ& theRes);
protected:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
long myPrecision;
};
class FreeBorders: public virtual Predicate{
public:
FreeBorders();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
protected:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
};
class BadOrientedVolume: public virtual Predicate{
public:
BadOrientedVolume();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
protected:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
};
class FreeEdges: public virtual Predicate{
public:
FreeEdges();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
static bool IsFreeEdge( const SMDS_MeshNode** theNodes, const int theFaceId );
void GetBoreders(TBorders& theBorders);
protected:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
};
typedef boost::shared_ptr<FreeEdges> FreeEdgesPtr;
{
public:
RangeOfIds();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theNodeId );
virtual SMDSAbs_ElementType GetType() const;
virtual void SetType( SMDSAbs_ElementType theType );
bool SetRangeStr( const TCollection_AsciiString& );
protected:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
TColStd_SequenceOfInteger myMin;
TColStd_SequenceOfInteger myMax;
public:
Comparator();
virtual ~Comparator();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual void SetMargin(double theValue);
virtual void SetNumFunctor(NumericalFunctorPtr theFunct);
virtual bool IsSatisfy( long theElementId ) = 0;
LogicalNOT();
virtual ~LogicalNOT();
virtual bool IsSatisfy( long theElementId );
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual void SetPredicate(PredicatePtr thePred);
virtual SMDSAbs_ElementType GetType() const;
public:
LogicalBinary();
virtual ~LogicalBinary();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual void SetPredicate1(PredicatePtr thePred);
virtual void SetPredicate2(PredicatePtr thePred);
virtual SMDSAbs_ElementType GetType() const;
ManifoldPart();
~ManifoldPart();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
// inoke when all parameters already set
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
TVectorOfFacePtr& theFaces ) const;
private:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
TColStd_MapOfInteger myMapIds;
TColStd_MapOfInteger myMapBadGeomIds;
TVectorOfFacePtr myAllFacePtr;
public:
ElementsOnSurface();
~ElementsOnSurface();
- virtual void SetMesh( SMDS_Mesh* theMesh );
+ virtual void SetMesh( const SMDS_Mesh* theMesh );
virtual bool IsSatisfy( long theElementId );
virtual SMDSAbs_ElementType GetType() const;
bool isOnSurface( const SMDS_MeshNode* theNode ) const;
private:
- SMDS_Mesh* myMesh;
+ const SMDS_Mesh* myMesh;
TColStd_MapOfInteger myIds;
SMDSAbs_ElementType myType;
Handle(Geom_Surface) mySurf;
Filter();
virtual ~Filter();
virtual void SetPredicate(PredicatePtr thePred);
+
typedef std::vector<long> TIdSequence;
- virtual TIdSequence GetElementsId( SMDS_Mesh* theMesh );
-
+
+ virtual
+ void
+ GetElementsId( const SMDS_Mesh* theMesh,
+ TIdSequence& theSequence );
+
+ static
+ void
+ GetElementsId( const SMDS_Mesh* theMesh,
+ PredicatePtr thePredicate,
+ TIdSequence& theSequence );
+
protected:
PredicatePtr myPredicate;
};
MED::TGeom::const_iterator anTGeomIter = aTGeom.begin();
for(; anTGeomIter != aTGeom.end(); anTGeomIter++){
const EGeometrieElement& aGeom = anTGeomIter->first;
- if(aGeom == ePOINT1) continue;
+
+ if (aGeom == ePOINT1) {
+ continue;
+
+ } else if (aGeom == ePOLYGONE) {
+ PPolygoneInfo aPolygoneInfo = aMed->GetPPolygoneInfo(aMeshInfo,anEntity,aGeom);
+ EBooleen anIsElemNum = takeNumbers ? aPolygoneInfo->IsElemNum() : eFAUX;
+
+ TElemNum aConn = aPolygoneInfo->GetConnectivite();
+ TElemNum aIndex = aPolygoneInfo->GetIndex();
+
+ TInt nbPolygons = aPolygoneInfo->GetNbElem();
+
+ for (TInt iPG = 0; iPG < nbPolygons; iPG++) {
+ // get nodes
+ TInt aCurrPG_FirstNodeIndex = aIndex[iPG] - 1;
+ int nbNodes = aPolygoneInfo->GetNbConn(iPG);
+ std::vector<int> nodes_ids (nbNodes);
+ //for (TInt inode = 0; inode < nbNodes; inode++) {
+ // nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+ //}
+#ifdef _EDF_NODE_IDS_
+ if (anIsNodeNum) {
+ for (TInt inode = 0; inode < nbNodes; inode++) {
+ nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPG_FirstNodeIndex + inode] - 1);
+ }
+ } else {
+ for (TInt inode = 0; inode < nbNodes; inode++) {
+ nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+ }
+ }
+#else
+ for (TInt inode = 0; inode < nbNodes; inode++) {
+ nodes_ids[inode] = aConn[aCurrPG_FirstNodeIndex + inode];
+ }
+#endif
+
+ bool isRenum = false;
+ SMDS_MeshElement* anElement = NULL;
+ TInt aFamNum = aPolygoneInfo->GetFamNum(iPG);
+
+ try {
+ if (anIsElemNum) {
+ anElement = myMesh->AddPolygonalFaceWithID
+ (nodes_ids, aPolygoneInfo->GetElemNum(iPG));
+ }
+ if (!anElement) {
+ std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+ for (int inode = 0; inode < nbNodes; inode++) {
+ nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
+ }
+ anElement = myMesh->AddPolygonalFace(nodes);
+ isRenum = anIsElemNum;
+ }
+ } catch (const std::exception& exc) {
+ aResult = DRS_FAIL;
+ } catch (...) {
+ aResult = DRS_FAIL;
+ }
+
+ if (!anElement) {
+ aResult = DRS_WARN_SKIP_ELEM;
+ } else {
+ if (isRenum) {
+ anIsElemNum = eFAUX;
+ takeNumbers = false;
+ if (aResult < DRS_WARN_RENUMBER)
+ aResult = DRS_WARN_RENUMBER;
+ }
+ if (myFamilies.find(aFamNum) != myFamilies.end()) {
+ // Save reference to this element from its family
+ myFamilies[aFamNum]->AddElement(anElement);
+ myFamilies[aFamNum]->SetType(anElement->GetType());
+ }
+ }
+ } // for (TInt iPG = 0; iPG < nbPolygons; iPG++)
+ continue;
+
+ } else if (aGeom == ePOLYEDRE) {
+ PPolyedreInfo aPolyedreInfo = aMed->GetPPolyedreInfo(aMeshInfo,anEntity,aGeom);
+ EBooleen anIsElemNum = takeNumbers ? aPolyedreInfo->IsElemNum() : eFAUX;
+
+ TElemNum aConn = aPolyedreInfo->GetConnectivite();
+ TElemNum aFacesIndex = aPolyedreInfo->GetFacesIndex();
+ TElemNum aIndex = aPolyedreInfo->GetIndex();
+
+ TInt nbPolyedres = aPolyedreInfo->GetNbElem();
+
+ for (int iPE = 0; iPE < nbPolyedres; iPE++) {
+ // get faces
+ int aCurrPE_FirstFaceIndex = aIndex[iPE] - 1;
+ int aNextPE_FirstFaceIndex = aIndex[iPE + 1] - 1;
+ int nbFaces = aNextPE_FirstFaceIndex - aCurrPE_FirstFaceIndex;
+ std::vector<int> quantities (nbFaces);
+ for (int iFa = 0; iFa < nbFaces; iFa++) {
+ int aCurrFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa] - 1;
+ int aNextFace_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex + iFa + 1] - 1;
+
+ int nbNodes = aNextFace_FirstNodeIndex - aCurrFace_FirstNodeIndex;
+ quantities[iFa] = nbNodes;
+ }
+
+ // get nodes
+ int aCurrPE_FirstNodeIndex = aFacesIndex[aCurrPE_FirstFaceIndex] - 1;
+ int nbPENodes = aPolyedreInfo->GetNbConn(iPE);
+ std::vector<int> nodes_ids (nbPENodes);
+ //for (int inode = 0; inode < nbPENodes; inode++) {
+ // nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+ //}
+#ifdef _EDF_NODE_IDS_
+ if (anIsNodeNum) {
+ for (int inode = 0; inode < nbPENodes; inode++) {
+ nodes_ids[inode] = aNodeInfo->GetElemNum(aConn[aCurrPE_FirstNodeIndex + inode] - 1);
+ }
+ } else {
+ for (int inode = 0; inode < nbPENodes; inode++) {
+ nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+ }
+ }
+#else
+ for (int inode = 0; inode < nbPENodes; inode++) {
+ nodes_ids[inode] = aConn[aCurrPE_FirstNodeIndex + inode];
+ }
+#endif
+
+ bool isRenum = false;
+ SMDS_MeshElement* anElement = NULL;
+ TInt aFamNum = aPolyedreInfo->GetFamNum(iPE);
+
+ try {
+ if (anIsElemNum) {
+ anElement = myMesh->AddPolyhedralVolumeWithID
+ (nodes_ids, quantities, aPolyedreInfo->GetElemNum(iPE));
+ }
+ if (!anElement) {
+ std::vector<const SMDS_MeshNode*> nodes (nbPENodes);
+ for (int inode = 0; inode < nbPENodes; inode++) {
+ nodes[inode] = FindNode(myMesh, nodes_ids[inode]);
+ }
+ anElement = myMesh->AddPolyhedralVolume(nodes, quantities);
+ isRenum = anIsElemNum;
+ }
+ } catch (const std::exception& exc) {
+ aResult = DRS_FAIL;
+ } catch (...) {
+ aResult = DRS_FAIL;
+ }
+
+ if (!anElement) {
+ aResult = DRS_WARN_SKIP_ELEM;
+ } else {
+ if (isRenum) {
+ anIsElemNum = eFAUX;
+ takeNumbers = false;
+ if (aResult < DRS_WARN_RENUMBER)
+ aResult = DRS_WARN_RENUMBER;
+ }
+ if (myFamilies.find(aFamNum) != myFamilies.end()) {
+ // Save reference to this element from its family
+ myFamilies[aFamNum]->AddElement(anElement);
+ myFamilies[aFamNum]->SetType(anElement->GetType());
+ }
+ }
+ } // for (int iPE = 0; iPE < nbPolyedres; iPE++)
+ continue;
+
+ } else {
+ }
+
PCellInfo aCellInfo = aMed->GetPCellInfo(aMeshInfo,anEntity,aGeom);
EBooleen anIsElemNum = takeNumbers ? aCellInfo->IsElemNum() : eFAUX;
TInt aNbElems = aCellInfo->GetNbElem();
SMDS_MeshElement* anElement = NULL;
TInt aFamNum = aCellInfo->GetFamNum(iElem);
try{
+ //MESSAGE("Try to create element # " << iElem << " with id = "
+ // << aCellInfo->GetElemNum(iElem));
switch(aGeom){
case eSEG2:
case eSEG3:
for (; anElemsIter != anElements.end(); anElemsIter++)
{
element = *anElemsIter;
- theGroup->SMDSGroup().Add(element);
+ theGroup->SMDSGroup().Add(element);
}
if ( element )
theGroup->SetType( element->GetType() );
#include "SMESHDS_Mesh.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+
#include "utilities.h"
#include "MED_Utilities.hxx"
void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName)
{
- return SetFile(theFileName,MED::eV2_1);
+ return SetFile(theFileName,MED::eV2_2);
}
void DriverMED_W_SMESHDS_Mesh::SetMeshName(const std::string& theMeshName)
MED::TIntVector aQuadConn;
aQuadConn.reserve(aNbElems*aNbQuadConn);
+ MED::TIntVector aPolygoneElemNums;
+ aPolygoneElemNums.reserve(aNbElems);
+ MED::TIntVector aPolygoneInds;
+ aPolygoneInds.reserve(aNbElems + 1);
+ aPolygoneInds.push_back(1); // reference on the first element in the connectivities
+ MED::TIntVector aPolygoneFamilyNums;
+ aPolygoneFamilyNums.reserve(aNbElems);
+ MED::TIntVector aPolygoneConn;
+ aPolygoneConn.reserve(aNbElems*aNbQuadConn);
+
for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
const SMDS_MeshFace* anElem = anIter->next();
TInt aNbNodes = anElem->NbNodes();
MED::TIntVector* anElemNums;
MED::TIntVector* aFamilyNums;
MED::TIntVector* aConnectivity;
- switch(aNbNodes){
- case 3:
- aNbConnectivity = aNbTriaConn;
- anElemNums = &anTriaElemNums;
- aFamilyNums = &aTriaFamilyNums;
- aConnectivity = &aTriaConn;
- break;
- case 4:
- aNbConnectivity = aNbQuadConn;
- anElemNums = &aQuadElemNums;
- aFamilyNums = &aQuadFamilyNums;
- aConnectivity = &aQuadConn;
- break;
- }
+ if (anElem->IsPoly()) {
+ aNbConnectivity = aNbNodes;
+ anElemNums = &aPolygoneElemNums;
+ aFamilyNums = &aPolygoneFamilyNums;
+ aConnectivity = &aPolygoneConn;
+ } else {
+ switch(aNbNodes){
+ case 3:
+ aNbConnectivity = aNbTriaConn;
+ anElemNums = &anTriaElemNums;
+ aFamilyNums = &aTriaFamilyNums;
+ aConnectivity = &aTriaConn;
+ break;
+ case 4:
+ aNbConnectivity = aNbQuadConn;
+ anElemNums = &aQuadElemNums;
+ aFamilyNums = &aQuadFamilyNums;
+ aConnectivity = &aQuadConn;
+ break;
+ default:
+ break;
+ }
+ }
MED::TIntVector aVector(aNbNodes);
for(TInt iNode = 0; aNodesIter->more(); iNode++){
const SMDS_MeshElement* aNode = aNodesIter->next();
+#ifdef _EDF_NODE_IDS_
+ aVector[iNode] = aNodeIdMap[aNode->GetID()];
+#else
aVector[iNode] = aNode->GetID();
+#endif
}
TInt aSize = aConnectivity->size();
aConnectivity->resize(aSize+aNbConnectivity);
- // There is some differnce between SMDS and MED in cells mapping
-#ifdef _EDF_NODE_IDS_
- switch(aNbNodes){
- case 4:
- (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
- (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[1]];
- (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[3]];
- (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[2]];
- default:
- for(TInt iNode = 0; iNode < aNbNodes; iNode++)
- (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
- }
-#else
+ // There is some differences between SMDS and MED in cells mapping
switch(aNbNodes){
case 4:
(*aConnectivity)[aSize+0] = aVector[0];
for(TInt iNode = 0; iNode < aNbNodes; iNode++)
(*aConnectivity)[aSize+iNode] = aVector[iNode];
}
-#endif
+
+ if (anElem->IsPoly()) {
+ // fill indices for polygonal element
+ TInt aPrevPos = aPolygoneInds.back();
+ aPolygoneInds.push_back(aPrevPos + aNbNodes);
+ }
+
anElemNums->push_back(anElem->GetID());
if (anElemFamMap.find(anElem) != anElemFamMap.end())
MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eQUAD4<<"; aNbElems = "<<aNbElems);
myMed->SetCellInfo(aCellInfo);
}
+ if(TInt aNbElems = aPolygoneElemNums.size()){
+ // add one element in connectivities,
+ // referenced by the last element in indices
+ aPolygoneConn.push_back(0);
+
+ PPolygoneInfo aCellInfo = myMed->CrPolygoneInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ ePOLYGONE,
+ SMDS_MED_CONNECTIVITY,
+ aPolygoneConn,
+ aPolygoneInds,
+ aPolygoneFamilyNums,
+ aPolygoneElemNums);
+ MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYGONE<<"; aNbElems = "<<aNbElems);
+ myMed->SetPolygoneInfo(aCellInfo);
+ }
}
// Storing SMDS Volumes
MED::TIntVector aHexaConn;
aHexaConn.reserve(aNbElems*aNbHexaConn);
+ MED::TIntVector aPolyedreElemNums;
+ aPolyedreElemNums.reserve(aNbElems);
+ MED::TIntVector aPolyedreInds;
+ aPolyedreInds.reserve(aNbElems + 1);
+ aPolyedreInds.push_back(1); // reference on the first element in the faces
+ MED::TIntVector aPolyedreFaces;
+ aPolyedreFaces.reserve(aNbElems + 1);
+ aPolyedreFaces.push_back(1); // reference on the first element in the connectivities
+ MED::TIntVector aPolyedreFamilyNums;
+ aPolyedreFamilyNums.reserve(aNbElems);
+ MED::TIntVector aPolyedreConn;
+ aPolyedreConn.reserve(aNbElems*aNbHexaConn);
+
for(TInt iElem = 0; iElem < aNbElems && anIter->more(); iElem++){
const SMDS_MeshVolume* anElem = anIter->next();
- TInt aNbNodes = anElem->NbNodes();
- SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
- TInt aNbConnectivity;
- MED::TIntVector* anElemNums;
- MED::TIntVector* aFamilyNums;
- MED::TIntVector* aConnectivity;
- switch(aNbNodes){
- case 4:
- aNbConnectivity = aNbTetraConn;
- anElemNums = &anTetraElemNums;
- aFamilyNums = &aTetraFamilyNums;
- aConnectivity = &aTetraConn;
- break;
- case 5:
- aNbConnectivity = aNbPyraConn;
- anElemNums = &anPyraElemNums;
- aFamilyNums = &aPyraFamilyNums;
- aConnectivity = &aPyraConn;
- break;
- case 6:
- aNbConnectivity = aNbPentaConn;
- anElemNums = &anPentaElemNums;
- aFamilyNums = &aPentaFamilyNums;
- aConnectivity = &aPentaConn;
- break;
- case 8:
- aNbConnectivity = aNbHexaConn;
- anElemNums = &aHexaElemNums;
- aFamilyNums = &aHexaFamilyNums;
- aConnectivity = &aHexaConn;
- }
- MED::TIntVector aVector(aNbNodes);
- for(TInt iNode = 0; aNodesIter->more(); iNode++){
- const SMDS_MeshElement* aNode = aNodesIter->next();
- aVector[iNode] = aNode->GetID();
- }
- TInt aSize = aConnectivity->size();
- aConnectivity->resize(aSize+aNbConnectivity);
- // There is some difference between SMDS and MED in cells mapping
+ MED::TIntVector* anElemNums;
+ MED::TIntVector* aFamilyNums;
+
+ if (anElem->IsPoly()) {
+ const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+ (const SMDS_PolyhedralVolumeOfNodes*) anElem;
+ if (!aPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ continue;
+ }
+
+ anElemNums = &aPolyedreElemNums;
+ aFamilyNums = &aPolyedreFamilyNums;
+
+ TInt aNodeId, aNbFaces = aPolyedre->NbFaces();
+ for (int iface = 1; iface <= aNbFaces; iface++) {
+ int aNbFaceNodes = aPolyedre->NbFaceNodes(iface);
+ for (int inode = 1; inode <= aNbFaceNodes; inode++) {
+ aNodeId = aPolyedre->GetFaceNode(iface, inode)->GetID();
#ifdef _EDF_NODE_IDS_
- switch(aNbNodes){
- case 5:
- (*aConnectivity)[aSize+0] = aNodeIdMap[aVector[0]];
- (*aConnectivity)[aSize+1] = aNodeIdMap[aVector[3]];
- (*aConnectivity)[aSize+2] = aNodeIdMap[aVector[2]];
- (*aConnectivity)[aSize+3] = aNodeIdMap[aVector[1]];
- (*aConnectivity)[aSize+4] = aNodeIdMap[aVector[4]];
- default:
- for(TInt iNode = 0; iNode < aNbNodes; iNode++)
- (*aConnectivity)[aSize+iNode] = aNodeIdMap[aVector[iNode]];
- }
+ aPolyedreConn.push_back(aNodeIdMap[aNodeId]);
#else
- switch(aNbNodes){
- case 5:
- (*aConnectivity)[aSize+0] = aVector[0];
- (*aConnectivity)[aSize+1] = aVector[3];
- (*aConnectivity)[aSize+2] = aVector[2];
- (*aConnectivity)[aSize+3] = aVector[1];
- (*aConnectivity)[aSize+4] = aVector[4];
- default:
- for(TInt iNode = 0; iNode < aNbNodes; iNode++)
- (*aConnectivity)[aSize+iNode] = aVector[iNode];
- }
+ aPolyedreConn.push_back(aNodeId);
#endif
- anElemNums->push_back(anElem->GetID());
+ }
+ TInt aPrevPos = aPolyedreFaces.back();
+ aPolyedreFaces.push_back(aPrevPos + aNbFaceNodes);
+ }
+ TInt aPrevPos = aPolyedreInds.back();
+ aPolyedreInds.push_back(aPrevPos + aNbFaces);
+
+ } else {
+ TInt aNbNodes = anElem->NbNodes();
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ TInt aNbConnectivity;
+ MED::TIntVector* aConnectivity;
+ switch(aNbNodes){
+ case 4:
+ aNbConnectivity = aNbTetraConn;
+ anElemNums = &anTetraElemNums;
+ aFamilyNums = &aTetraFamilyNums;
+ aConnectivity = &aTetraConn;
+ break;
+ case 5:
+ aNbConnectivity = aNbPyraConn;
+ anElemNums = &anPyraElemNums;
+ aFamilyNums = &aPyraFamilyNums;
+ aConnectivity = &aPyraConn;
+ break;
+ case 6:
+ aNbConnectivity = aNbPentaConn;
+ anElemNums = &anPentaElemNums;
+ aFamilyNums = &aPentaFamilyNums;
+ aConnectivity = &aPentaConn;
+ break;
+ case 8:
+ aNbConnectivity = aNbHexaConn;
+ anElemNums = &aHexaElemNums;
+ aFamilyNums = &aHexaFamilyNums;
+ aConnectivity = &aHexaConn;
+ }
+
+ TInt aSize = aConnectivity->size();
+ aConnectivity->resize(aSize + aNbConnectivity);
+
+ MED::TIntVector aVector(aNbNodes);
+ for(TInt iNode = 0; aNodesIter->more(); iNode++){
+ const SMDS_MeshElement* aNode = aNodesIter->next();
+#ifdef _EDF_NODE_IDS_
+ aVector[iNode] = aNodeIdMap[aNode->GetID()];
+#else
+ aVector[iNode] = aNode->GetID();
+#endif
+ }
+ // There is some difference between SMDS and MED in cells mapping
+ switch(aNbNodes){
+ case 5:
+ (*aConnectivity)[aSize+0] = aVector[0];
+ (*aConnectivity)[aSize+1] = aVector[3];
+ (*aConnectivity)[aSize+2] = aVector[2];
+ (*aConnectivity)[aSize+3] = aVector[1];
+ (*aConnectivity)[aSize+4] = aVector[4];
+ default:
+ for(TInt iNode = 0; iNode < aNbNodes; iNode++)
+ (*aConnectivity)[aSize+iNode] = aVector[iNode];
+ }
+ }
+
+ anElemNums->push_back(anElem->GetID());
if (anElemFamMap.find(anElem) != anElemFamMap.end())
aFamilyNums->push_back(anElemFamMap[anElem]);
MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<eHEXA8<<"; aNbElems = "<<aNbElems);
myMed->SetCellInfo(aCellInfo);
}
+ if(TInt aNbElems = aPolyedreElemNums.size()){
+ // add one element in connectivities,
+ // referenced by the last element in faces
+ aPolyedreConn.push_back(0);
+
+ PPolyedreInfo aCellInfo = myMed->CrPolyedreInfo(aMeshInfo,
+ SMDS_MED_ENTITY,
+ ePOLYEDRE,
+ SMDS_MED_CONNECTIVITY,
+ aPolyedreConn,
+ aPolyedreFaces,
+ aPolyedreInds,
+ aPolyedreFamilyNums,
+ aPolyedreElemNums);
+ MESSAGE("Perform - anEntity = "<<SMDS_MED_ENTITY<<"; aGeom = "<<ePOLYEDRE<<"; aNbElems = "<<aNbElems);
+ myMed->SetPolyedreInfo(aCellInfo);
+ }
}
}catch(const std::exception& exc){
INFOS("Follow exception was cought:\n\t"<<exc.what());
// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
#include <stdio.h>
-
-#include "DriverSTL_R_SMDS_Mesh.h"
-
-#include "SMDS_Mesh.hxx"
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
#include <gp_Pnt.hxx>
-#include <OSD_Path.hxx>
-#include <OSD_File.hxx>
-#include <OSD_FromWhere.hxx>
-#include <OSD_Protection.hxx>
-#include <OSD_SingleProtection.hxx>
-#include <NCollection_DataMap.hxx>
-#include <Standard_NoMoreObject.hxx>
-
-#include "utilities.h"
-
-static const int HEADER_SIZE = 84;
-static const int SIZEOF_STL_FACET = 50;
-//static const int STL_MIN_FILE_SIZE = 284;
-static const int ASCII_LINES_PER_FACET = 7;
-
-static Standard_Real tab1[3];
-static Standard_Real tab2[3];
-
-typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*> DriverSTL_DataMapOfPntNodePtr;
-//typedef NCollection_BaseCollection<SMDS_MeshNodePtr> DriverSTL_ColOfNodePtr;
-
//=======================================================================
//function : HashCode
//purpose :
//=======================================================================
inline Standard_Integer HashCode
- (const gp_Pnt& point, const Standard_Integer Upper)
+ (const gp_Pnt& point, Standard_Integer Upper)
{
union
{
return ::HashCode(U.I[0]/23+U.I[1]/19+U.I[2]/17+U.I[3]/13+U.I[4]/11+U.I[5]/7,Upper);
}
-
+static Standard_Real tab1[3];
+static Standard_Real tab2[3];
//=======================================================================
//function : IsEqual
//purpose :
point2.Coord(tab2[0],tab2[1],tab2[2]);
return (memcmp(tab1,tab2,sizeof(tab1)) == 0);
}
+#include "DriverSTL_R_SMDS_Mesh.h"
+
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+
+#include <OSD_Path.hxx>
+#include <OSD_File.hxx>
+#include <OSD_FromWhere.hxx>
+#include <OSD_Protection.hxx>
+#include <OSD_SingleProtection.hxx>
+#include <Standard_NoMoreObject.hxx>
+#include "utilities.h"
+
+static const int HEADER_SIZE = 84;
+static const int SIZEOF_STL_FACET = 50;
+//static const int STL_MIN_FILE_SIZE = 284;
+static const int ASCII_LINES_PER_FACET = 7;
+
+
+//typedef NCollection_BaseCollection<SMDS_MeshNodePtr> DriverSTL_ColOfNodePtr;
+
+
+#include <NCollection_DataMap.hxx>
+typedef NCollection_DataMap<gp_Pnt,SMDS_MeshNode*> DriverSTL_DataMapOfPntNodePtr;
//=======================================================================
//function : DriverSTL_R_SMDS_Mesh
//purpose :
BIN =
BIN_SRC =
-CPPFLAGS+=$(OCC_INCLUDES) $(VTK_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome \
+CPPFLAGS+=$(OCC_INCLUDES) $(VTK_INCLUDES) -I${KERNEL_ROOT_DIR}/include/salome -I${GUI_ROOT_DIR}/include/salome \
$(BOOST_CPPFLAGS) $(QT_INCLUDES)
-LDFLAGS+=$(OCC_KERNEL_LIBS) $(VTK_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -lSMDS \
- -lSalomeGUI -lSalomeObject -lSMESHControls
+LDFLAGS+=$(OCC_KERNEL_LIBS) $(VTK_LIBS) -L${KERNEL_ROOT_DIR}/lib/salome -L${GUI_ROOT_DIR}/lib/salome -lSMDS \
+ -lSalomeApp -lSalomeObject -lSMESHControls
@CONCLUDE@
#include "SMESH_ActorUtils.h"
#include "SMESH_DeviceActor.h"
#include "SMESH_ControlsDef.hxx"
-#include "SALOME_ExtractUnstructuredGrid.h"
+#include <VTKViewer_ExtractUnstructuredGrid.h>
-#include "QAD_Config.h"
+//#include "QAD_Config.h"
#include <qstringlist.h>
#include <vtkTimeStamp.h>
#include "utilities.h"
#ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
#else
static int MYDEBUG = 0;
#endif
float aLineWidth = SMESH::GetFloat("SMESH:SettingsWidth",1);
vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
- SALOME_ExtractUnstructuredGrid* aFilter = NULL;
+ VTKViewer_ExtractUnstructuredGrid* aFilter = NULL;
//Definition 2D and 3D divices of the actor
//-----------------------------------------
my2DActor->SetBackfaceProperty(myBackSurfaceProp);
my2DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
aFilter = my2DActor->GetExtractUnstructuredGrid();
- aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
aFilter->RegisterCellsWithType(VTK_TRIANGLE);
aFilter->RegisterCellsWithType(VTK_POLYGON);
aFilter->RegisterCellsWithType(VTK_QUAD);
my3DActor->SetBackfaceProperty(myBackSurfaceProp);
my3DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
aFilter = my3DActor->GetExtractUnstructuredGrid();
- aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
aFilter->RegisterCellsWithType(VTK_TETRA);
aFilter->RegisterCellsWithType(VTK_VOXEL);
aFilter->RegisterCellsWithType(VTK_HEXAHEDRON);
aFilter->RegisterCellsWithType(VTK_WEDGE);
aFilter->RegisterCellsWithType(VTK_PYRAMID);
-
+ aFilter->RegisterCellsWithType(VTK_CONVEX_POINT_SET);
//Definition 1D divice of the actor
//---------------------------------
my1DActor->SetProperty(myEdgeProp);
my1DActor->SetRepresentation(SMESH_DeviceActor::eSurface);
aFilter = my1DActor->GetExtractUnstructuredGrid();
- aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
aFilter->RegisterCellsWithType(VTK_LINE);
my1DProp = vtkProperty::New();
my1DExtActor->SetProperty(my1DExtProp);
my1DExtActor->SetRepresentation(SMESH_DeviceActor::eInsideframe);
aFilter = my1DExtActor->GetExtractUnstructuredGrid();
- aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
aFilter->RegisterCellsWithType(VTK_LINE);
myNodeActor->SetProperty(myNodeProp);
myNodeActor->SetRepresentation(SMESH_DeviceActor::ePoint);
aFilter = myNodeActor->GetExtractUnstructuredGrid();
- aFilter->SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints);
+ aFilter->SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
//Definition of Pickable and Highlitable engines
vtkTextProperty* aScalarBarTitleProp = vtkTextProperty::New();
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) {
+/* if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleColor" ) ) {
QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleColor" ), false );
aScalarBarTitleProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
- ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
}
- else
+ else*/
aScalarBarTitleProp->SetColor( 1.0, 1.0, 1.0 );
aScalarBarTitleProp->SetFontFamilyToArial();
- if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ){
+ /*if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarTitleFont" ) ){
if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Arial" )
aScalarBarTitleProp->SetFontFamilyToArial();
else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Courier" )
aScalarBarTitleProp->SetFontFamilyToCourier();
else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleFont" ) == "Times" )
aScalarBarTitleProp->SetFontFamilyToTimes();
- }
+ }*/
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleBold" ) == "true" )
aScalarBarTitleProp->BoldOn();
- else
+ else*/
aScalarBarTitleProp->BoldOff();
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleItalic" ) == "true" )
aScalarBarTitleProp->ItalicOn();
- else
+ else*/
aScalarBarTitleProp->ItalicOff();
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarTitleShadow" ) == "true" )
aScalarBarTitleProp->ShadowOn();
- else
+ else*/
aScalarBarTitleProp->ShadowOff();
myScalarBarActor->SetTitleTextProperty( aScalarBarTitleProp );
vtkTextProperty* aScalarBarLabelProp = vtkTextProperty::New();
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) {
+ /*if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelColor" ) ) {
QStringList aTColor = QStringList::split( ":", QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelColor" ), false );
aScalarBarLabelProp->SetColor( ( aTColor.count() > 0 ? aTColor[0].toInt()/255. : 1.0 ),
- ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
+ ( aTColor.count() > 1 ? aTColor[1].toInt()/255. : 1.0 ),
( aTColor.count() > 2 ? aTColor[2].toInt()/255. : 1.0 ) );
}
- else
+ else*/
aScalarBarLabelProp->SetColor( 1.0, 1.0, 1.0 );
aScalarBarLabelProp->SetFontFamilyToArial();
- if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ){
+ /*if( QAD_CONFIG->hasSetting( "SMESH:ScalarBarLabelFont" ) ){
if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Arial" )
aScalarBarLabelProp->SetFontFamilyToArial();
else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Courier" )
aScalarBarLabelProp->SetFontFamilyToCourier();
else if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelFont" ) == "Times" )
aScalarBarLabelProp->SetFontFamilyToTimes();
- }
+ }*/
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelBold" ) == "true" )
aScalarBarLabelProp->BoldOn();
- else
+ else*/
aScalarBarLabelProp->BoldOff();
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelItalic" ) == "true" )
aScalarBarLabelProp->ItalicOn();
- else
+ else*/
aScalarBarLabelProp->ItalicOff();
- if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" )
+ /*if ( QAD_CONFIG->getSetting( "SMESH:ScalarBarLabelShadow" ) == "true" )
aScalarBarLabelProp->ShadowOn();
- else
+ else*/
aScalarBarLabelProp->ShadowOff();
myScalarBarActor->SetLabelTextProperty( aScalarBarLabelProp );
aScalarBarLabelProp->Delete();
- if ( QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" )
+ /*if ( QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" )
myScalarBarActor->SetOrientationToHorizontal();
- else
+ else*/
myScalarBarActor->SetOrientationToVertical();
- float aXVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.20 : 0.01;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) )
- aXVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toFloat();
- float aYVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.01 : 0.1;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) )
- aYVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toFloat();
+ float aXVal = 0.01; //QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.20 : 0.01;
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarXPosition" ) )
+ // aXVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarXPosition" ).toFloat();
+ float aYVal = 0.1; //QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.01 : 0.1;
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarYPosition" ) )
+ // aYVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarYPosition" ).toFloat();
myScalarBarActor->SetPosition( aXVal, aYVal );
- float aWVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.60 : 0.10;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) )
- aWVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toFloat();
+ float aWVal = 0.1; //QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.60 : 0.10;
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarWidth" ) )
+ // aWVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarWidth" ).toFloat();
myScalarBarActor->SetWidth( aWVal );
- float aHVal = QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.12 : 0.80;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) )
- aHVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toFloat();
+ float aHVal = 0.8; //QAD_CONFIG->getSetting("SMESH:ScalarBarOrientation") == "Horizontal" ? 0.12 : 0.80;
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarHeight" ) )
+ // aHVal = QAD_CONFIG->getSetting( "SMESH:ScalarBarHeight" ).toFloat();
myScalarBarActor->SetHeight( aHVal );
int anIntVal = 5;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) )
- anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfLabels").toInt();
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfLabels" ) )
+ // anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfLabels").toInt();
myScalarBarActor->SetNumberOfLabels(anIntVal == 0? 5: anIntVal);
anIntVal = 64;
- if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) )
- anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfColors").toInt();
+ //if ( QAD_CONFIG->hasSetting( "SMESH:ScalarBarNbOfColors" ) )
+ // anIntVal = QAD_CONFIG->getSetting("SMESH:ScalarBarNbOfColors").toInt();
myScalarBarActor->SetMaximumNumberOfColors(anIntVal == 0? 64: anIntVal);
myPtsMaskPoints = vtkMaskPoints::New();
myPtsMaskPoints->SetInput(myPointsNumDataSet);
myPtsMaskPoints->SetOnRatio(1);
-
+
myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
myPtsSelectVisiblePoints->SelectInvisibleOff();
bool theCheckEntityMode)
{
myControlMode = eNone;
- theCheckEntityMode &= QAD_CONFIG->getSetting("SMESH:DispayEntity") == "true";
+ //theCheckEntityMode &= QAD_CONFIG->getSetting("SMESH:DispayEntity") == "true";
my1DActor->GetMapper()->SetScalarVisibility(false);
my2DActor->GetMapper()->SetScalarVisibility(false);
//SetIsShrunkable(theGrid->GetNumberOfCells() > 10);
SetIsShrunkable(true);
- QString aMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
+ //QString aMode = QAD_CONFIG->getSetting("SMESH:DisplayMode");
SetRepresentation(-1);
+ /*
if(aMode.compare("Wireframe") == 0){
SetRepresentation(eEdge);
}else if(aMode.compare("Shading") == 0){
}else if(aMode.compare("Nodes") == 0){
SetRepresentation(ePoint);
}
-
- aMode = QAD_CONFIG->getSetting("SMESH:Shrink");
+ */
+ /*aMode = QAD_CONFIG->getSetting("SMESH:Shrink");
if(aMode == "yes"){
SetShrink();
- }
+ }*/
myTimeStamp->Modified();
Modified();
}
-void SMESH_ActorDef::SetTransform(SALOME_Transform* theTransform){
+void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
myNodeActor->SetTransform(theTransform);
myBaseActor->SetTransform(theTransform);
myBaseActor->myGeomFilter->SetInside(myEntityMode != myEntityState);
myEntityMode = theMode;
- SALOME_ExtractUnstructuredGrid* aFilter = NULL;
+ VTKViewer_ExtractUnstructuredGrid* aFilter = NULL;
aFilter = myBaseActor->GetExtractUnstructuredGrid();
aFilter->ClearRegisteredCellsWithType();
- aFilter->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ aFilter->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
if(myEntityMode & eEdges){
if (MYDEBUG) MESSAGE("EDGES");
myHighlitableActor->SetHighlited(anIsVisible);
myHighlitableActor->SetVisibility(anIsVisible);
myHighlitableActor->GetExtractUnstructuredGrid()->
- SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::eCells);
+ SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::eCells);
myHighlitableActor->SetRepresentation(SMESH_DeviceActor::eWireframe);
}else if(myRepresentation == ePoint || GetPointRepresentation()){
myHighlitableActor->SetHighlited(anIsVisible);
myHighlitableActor->SetVisibility(anIsVisible);
myHighlitableActor->GetExtractUnstructuredGrid()->
- SetModeOfExtraction(SALOME_ExtractUnstructuredGrid::ePoints);
+ SetModeOfExtraction(VTKViewer_ExtractUnstructuredGrid::ePoints);
myHighlitableActor->SetRepresentation(SMESH_DeviceActor::ePoint);
}
}
#ifndef SMESH_ACTOR_H
#define SMESH_ACTOR_H
-#include "SALOME_Actor.h"
+#include <SALOME_Actor.h>
#include "SMESH_Object.h"
class vtkUnstructuredGrid;
return *this;
}
TVTKSmartPtr& operator=(T* r){ vtkSmartPointer<T>::operator=(r); return *this;}
- T* Get() const { return GetPointer();}
+ T* Get() const { return this->GetPointer();}
};
virtual bool GetPointRepresentation();
virtual float* GetBounds();
- virtual void SetTransform(SALOME_Transform* theTransform);
+ virtual void SetTransform(VTKViewer_Transform* theTransform);
virtual vtkUnstructuredGrid* GetUnstructuredGrid();
virtual vtkDataSet* GetInput();
#include "SMESH_ActorUtils.h"
-#include "QAD_Config.h"
+//#include "QAD_Config.h"
#include "utilities.h"
#include <vtkUnstructuredGrid.h>
float GetFloat(const QString& theValue, float theDefault){
if(theValue.isEmpty()) return theDefault;
- QString aValue = QAD_CONFIG->getSetting(theValue);
- if(aValue.isEmpty()) return theDefault;
- return aValue.toFloat();
+ //QString aValue = QAD_CONFIG->getSetting(theValue);
+ //if(aValue.isEmpty())
+ return theDefault;
+ //return aValue.toFloat();
}
void WriteUnstructuredGrid(vtkUnstructuredGrid* theGrid, const char* theFileName){
#include "SMESH_ControlsDef.hxx"
#include "SMESH_ActorUtils.h"
-#include "SALOME_Transform.h"
-#include "SALOME_TransformFilter.h"
-#include "SALOME_PassThroughFilter.h"
-#include "SALOME_ExtractUnstructuredGrid.h"
+#include <VTKViewer_Transform.h>
+#include <VTKViewer_TransformFilter.h>
+#include <VTKViewer_PassThroughFilter.h>
+#include <VTKViewer_ExtractUnstructuredGrid.h>
// VTK Includes
#include <vtkObjectFactory.h>
myExtractGeometry->SetReleaseDataFlag(true);
myIsImplicitFunctionUsed = false;
- myExtractUnstructuredGrid = SALOME_ExtractUnstructuredGrid::New();
+ myExtractUnstructuredGrid = VTKViewer_ExtractUnstructuredGrid::New();
myMergeFilter = vtkMergeFilter::New();
- myGeomFilter = SALOME_GeometryFilter::New();
+ myGeomFilter = VTKViewer_GeometryFilter::New();
- myTransformFilter = SALOME_TransformFilter::New();
+ myTransformFilter = VTKViewer_TransformFilter::New();
for(int i = 0; i < 6; i++)
- myPassFilter.push_back(SALOME_PassThroughFilter::New());
+ myPassFilter.push_back(VTKViewer_PassThroughFilter::New());
}
}
-SALOME_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){
+VTKViewer_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){
return myExtractUnstructuredGrid;
}
bool anIsInitialized = theFunctor;
myExtractUnstructuredGrid->ClearRegisteredCells();
myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
- myExtractUnstructuredGrid->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::ePassAll);
+ myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
myVisualObj->UpdateFunctor(theFunctor);
using namespace SMESH::Controls;
{
myExtractUnstructuredGrid->ClearRegisteredCells();
myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
- myExtractUnstructuredGrid->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::ePassAll);
+ myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
myVisualObj->UpdateFunctor(theFunctor);
using namespace SMESH::Controls;
if(FreeBorders* aFreeBorders = dynamic_cast<FreeBorders*>(theFunctor.get())){
- myExtractUnstructuredGrid->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::eAdding);
+ myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::eAdding);
vtkUnstructuredGrid* aGrid = myVisualObj->GetUnstructuredGrid();
vtkIdType aNbCells = aGrid->GetNumberOfCells();
for( vtkIdType i = 0; i < aNbCells; i++ ){
}
-void SMESH_DeviceActor::SetTransform(SALOME_Transform* theTransform){
+void SMESH_DeviceActor::SetTransform(VTKViewer_Transform* theTransform){
myTransformFilter->SetTransform(theTransform);
}
#ifndef SMESH_DEVICE_ACTOR_H
#define SMESH_DEVICE_ACTOR_H
-#include "SALOME_GeometryFilter.h"
+#include <VTKViewer_GeometryFilter.h>
#include "SMESH_Controls.hxx"
#include "SMESH_Object.h"
class vtkLookupTable;
class vtkImplicitBoolean;
-class SALOME_Transform;
-class SALOME_TransformFilter;
-class SALOME_PassThroughFilter;
-class SALOME_ExtractUnstructuredGrid;
+class VTKViewer_Transform;
+class VTKViewer_TransformFilter;
+class VTKViewer_PassThroughFilter;
+class VTKViewer_ExtractUnstructuredGrid;
class SMESH_ExtractGeometry;
virtual int GetElemObjId(int theVtkID);
virtual vtkCell* GetElemCell(int theObjID);
- virtual void SetTransform(SALOME_Transform* theTransform);
+ virtual void SetTransform(VTKViewer_Transform* theTransform);
virtual unsigned long int GetMTime();
float GetShrinkFactor();
virtual void SetVisibility(int theMode);
virtual int GetVisibility();
- SALOME_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
+ VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
vtkUnstructuredGrid* GetUnstructuredGrid();
void SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
bool myIsImplicitFunctionUsed;
vtkMergeFilter* myMergeFilter;
- SALOME_ExtractUnstructuredGrid* myExtractUnstructuredGrid;
+ VTKViewer_ExtractUnstructuredGrid* myExtractUnstructuredGrid;
bool myStoreClippingMapping;
- SALOME_GeometryFilter *myGeomFilter;
- SALOME_TransformFilter *myTransformFilter;
- std::vector<SALOME_PassThroughFilter*> myPassFilter;
+ VTKViewer_GeometryFilter *myGeomFilter;
+ VTKViewer_TransformFilter *myTransformFilter;
+ std::vector<VTKViewer_PassThroughFilter*> myPassFilter;
vtkShrinkFilter* myShrinkFilter;
bool myIsShrinkable;
#include "SMDS_Mesh.hxx"
#include "SMESH_Actor.h"
#include "SMESH_ControlsDef.hxx"
-#include "SALOME_ExtractUnstructuredGrid.h"
+#include <VTKViewer_ExtractUnstructuredGrid.h>
#include CORBA_SERVER_HEADER(SALOME_Exception)
}
+ inline void AddPolygonsWithID(SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+ for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+ int aFaceId = anIndexes[anIndexId++];
+
+ int aNbNodes = anIndexes[anIndexId++];
+ std::vector<int> nodes_ids (aNbNodes);
+ for (int i = 0; i < aNbNodes; i++) {
+ nodes_ids[i] = anIndexes[anIndexId++];
+ }
+
+ SMDS_MeshElement* anElem = theMesh->AddPolygonalFaceWithID(nodes_ids, aFaceId);
+ if (!anElem)
+ EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolygonalFaceWithID for ID = "
+ << anElemId);
+ }
+ }
+
+
inline void AddTetrasWithID(SMDS_Mesh* theMesh,
SMESH::log_array_var& theSeq,
CORBA::Long theId)
anIndexes[anIndexId+4],
anIndexes[anIndexId]);
if(!anElem)
- EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
}
}
anIndexes[anIndexId+5],
anIndexes[anIndexId]);
if(!anElem)
- EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
}
}
anIndexes[anIndexId+6],
anIndexes[anIndexId]);
if(!anElem)
- EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
}
}
anIndexes[anIndexId+8],
anIndexes[anIndexId]);
if(!anElem)
- EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddFaceWithID for ID = "<<anElemId);
+ EXCEPTION(runtime_error,"SMDS_Mesh::FindElement - cannot AddVolumeWithID for ID = "<<anElemId);
+ }
+ }
+
+
+ inline void AddPolyhedronsWithID (SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long anIndexId = 0, aNbElems = theSeq[theId].number;
+
+ for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++) {
+ int aFaceId = anIndexes[anIndexId++];
+
+ int aNbNodes = anIndexes[anIndexId++];
+ std::vector<int> nodes_ids (aNbNodes);
+ for (int i = 0; i < aNbNodes; i++) {
+ nodes_ids[i] = anIndexes[anIndexId++];
+ }
+
+ int aNbFaces = anIndexes[anIndexId++];
+ std::vector<int> quantities (aNbFaces);
+ for (int i = 0; i < aNbFaces; i++) {
+ quantities[i] = anIndexes[anIndexId++];
+ }
+
+ SMDS_MeshElement* anElem =
+ theMesh->AddPolyhedralVolumeWithID(nodes_ids, quantities, aFaceId);
+ if (!anElem)
+ EXCEPTION(runtime_error, "SMDS_Mesh::FindElement - cannot AddPolyhedralVolumeWithID for ID = "
+ << anElemId);
+ }
+ }
+
+
+ inline void ChangePolyhedronNodes (SMDS_Mesh* theMesh,
+ SMESH::log_array_var& theSeq,
+ CORBA::Long theId)
+ {
+ const SMESH::long_array& anIndexes = theSeq[theId].indexes;
+ CORBA::Long iind = 0, aNbElems = theSeq[theId].number;
+
+ for (CORBA::Long anElemId = 0; anElemId < aNbElems; anElemId++)
+ {
+ // find element
+ const SMDS_MeshElement* elem = FindElement(theMesh, anIndexes[iind++]);
+ // nb nodes
+ int nbNodes = anIndexes[iind++];
+ // nodes
+ std::vector<const SMDS_MeshNode*> aNodes (nbNodes);
+ for (int iNode = 0; iNode < nbNodes; iNode++) {
+ aNodes[iNode] = FindNode(theMesh, anIndexes[iind++]);
+ }
+ // nb faces
+ int nbFaces = anIndexes[iind++];
+ // quantities
+ std::vector<int> quantities (nbFaces);
+ for (int iFace = 0; iFace < nbFaces; iFace++) {
+ quantities[iFace] = anIndexes[iind++];
+ }
+ // change
+ theMesh->ChangePolyhedronNodes(elem, aNodes, quantities);
}
}
// purpose : Get type of VTK cell
//=================================================================================
static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
+ const bool thePoly,
const int theNbNodes )
{
switch( theType )
case SMDSAbs_Edge:
return theNbNodes == 2 ? VTK_LINE : VTK_EMPTY_CELL;
- case SMDSAbs_Face :
- if ( theNbNodes == 3 ) return VTK_TRIANGLE;
- else if ( theNbNodes == 4 ) return VTK_QUAD;
- else return VTK_EMPTY_CELL;
+ case SMDSAbs_Face :
+ if (thePoly && theNbNodes>2 ) return VTK_POLYGON;
+ else if ( theNbNodes == 3 ) return VTK_TRIANGLE;
+ else if ( theNbNodes == 4 ) return VTK_QUAD;
+ else return VTK_EMPTY_CELL;
- case SMDSAbs_Volume:
- if ( theNbNodes == 4 ) return VTK_TETRA;
- else if ( theNbNodes == 5 ) return VTK_PYRAMID;
- else if ( theNbNodes == 6 ) return VTK_WEDGE;
- else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
- else return VTK_EMPTY_CELL;
+ case SMDSAbs_Volume:
+ if (thePoly && theNbNodes>3 ) return VTK_CONVEX_POINT_SET;
+ else if ( theNbNodes == 4 ) return VTK_TETRA;
+ else if ( theNbNodes == 5 ) return VTK_PYRAMID;
+ else if ( theNbNodes == 6 ) return VTK_WEDGE;
+ else if ( theNbNodes == 8 ) return VTK_HEXAHEDRON;
+ else return VTK_EMPTY_CELL;
default: return VTK_EMPTY_CELL;
}
//=================================================================================
SMESH_VisualObjDef::SMESH_VisualObjDef()
{
- if(MYDEBUG) MESSAGE("SMESH_MeshObj - "<<this);
myGrid = vtkUnstructuredGrid::New();
}
SMESH_VisualObjDef::~SMESH_VisualObjDef()
{
- if(MYDEBUG) {
- MESSAGE("~SMESH_MeshObj - "<<this);
- myGrid->DebugOn();
- }
+ if ( MYDEBUG )
+ MESSAGE( "~SMESH_MeshObj - myGrid->GetReferenceCount() = " << myGrid->GetReferenceCount() );
myGrid->Delete();
}
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
switch(aType){
case SMDSAbs_Volume:{
- int* aConnectivities = NULL;
+ std::vector<int> aConnectivities;
GetConnect(aNodesIter,aConnect);
// Convertions connectivities from SMDS to VTK
- switch(aNbNodes){
- case 4:{
+ if (anElem->IsPoly() && aNbNodes > 3) { // POLYEDRE
+ for (int k = 0; k < aNbNodes; k++) {
+ aConnectivities.push_back(k);
+ }
+
+ } else if (aNbNodes == 4) {
static int anIds[] = {0,2,1,3};
- aConnectivities = anIds;
- break;
- }
- case 5:{
+ for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+
+ } else if (aNbNodes == 5) {
static int anIds[] = {0,3,2,1,4};
- aConnectivities = anIds;
- break;
- }
- case 6:{
+ for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+
+ } else if (aNbNodes == 6) {
static int anIds[] = {0,1,2,3,4,5};
- aConnectivities = anIds;
- break;
- }
- case 8:{
+ for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
+
+ } else if (aNbNodes == 8) {
static int anIds[] = {0,3,2,1,4,7,6,5};
- aConnectivities = anIds;
- break;
- }}
+ for (int k = 0; k < aNbNodes; k++) aConnectivities.push_back(anIds[k]);
- if(aConnectivities)
- for( vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++ )
+ } else {
+ }
+
+ if (aConnectivities.size() > 0) {
+ for (vtkIdType aNodeId = 0; aNodeId < aNbNodes; aNodeId++)
SetId(anIdList,mySMDS2VTKNodes,aConnect,aNodeId,aConnectivities[aNodeId]);
-
+ }
break;
}
default:
}
aConnectivity->InsertNextCell( anIdList );
- aCellTypesArray->InsertNextValue( getCellType( aType, aNbNodes ) );
+ aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
iElem++;
}
int nbNodes = anElem->NbNodes();
- if ( theEdgeNum < 1 || theEdgeNum > 4 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
+ if ( theEdgeNum < 0 || theEdgeNum > 3 || nbNodes != 3 && nbNodes != 4 || theEdgeNum > nbNodes )
return false;
int anIds[ nbNodes ];
while( anIter->more() )
anIds[ i++ ] = anIter->next()->GetID();
- if ( nbNodes != theEdgeNum )
+ if ( theEdgeNum < nbNodes - 1 )
{
- theNodeId1 = anIds[ theEdgeNum - 1 ];
- theNodeId2 = anIds[ theEdgeNum ];
+ theNodeId1 = anIds[ theEdgeNum ];
+ theNodeId2 = anIds[ theEdgeNum + 1 ];
}
else
{
if( !aLength )
return;
-
+
for ( CORBA::Long anId = 0; anId < aLength; anId++)
{
const SMESH::double_array& aCoords = aSeq[anId].coords;
const SMESH::long_array& anIndexes = aSeq[anId].indexes;
CORBA::Long anElemId = 0, aNbElems = aSeq[anId].number;
CORBA::Long aCommand = aSeq[anId].commandType;
-
+
switch(aCommand)
{
- case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_PYRAMID : AddPiramidsWithID( myMesh, aSeq, anId ); break;
- case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
- case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
-
+ case SMESH::ADD_NODE : AddNodesWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_EDGE : AddEdgesWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_TRIANGLE : AddTriasWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_QUADRANGLE : AddQuadsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_POLYGON : AddPolygonsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_TETRAHEDRON: AddTetrasWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_PYRAMID : AddPiramidsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_PRISM : AddPrismsWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_HEXAHEDRON : AddHexasWithID ( myMesh, aSeq, anId ); break;
+ case SMESH::ADD_POLYHEDRON : AddPolyhedronsWithID( myMesh, aSeq, anId ); break;
+
case SMESH::REMOVE_NODE:
for( ; anElemId < aNbElems; anElemId++ )
myMesh->RemoveNode( FindNode( myMesh, anIndexes[anElemId] ) );
// nb nodes
int nbNodes = anIndexes[i++];
// nodes
- ASSERT( nbNodes < 9 );
- const SMDS_MeshNode* aNodes[ 8 ];
+ //ASSERT( nbNodes < 9 );
+ const SMDS_MeshNode* aNodes[ nbNodes ];
for ( int iNode = 0; iNode < nbNodes; iNode++ )
aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] );
// change
}
break;
+ case SMESH::CHANGE_POLYHEDRON_NODES:
+ ChangePolyhedronNodes(myMesh, aSeq, anId);
+ break;
case SMESH::RENUMBER:
for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
{
#define SMESH_OBJECTDEF_H
// IDL Headers
-#include "SALOMEconfig.h"
+#include <SALOMEconfig.h>
#include CORBA_SERVER_HEADER(SMESH_Mesh)
#include CORBA_SERVER_HEADER(SMESH_Group)
SMDS_IteratorOfElements.cxx \
SMDS_VolumeOfFaces.cxx \
SMDS_VolumeOfNodes.cxx \
+ SMDS_PolyhedralVolumeOfNodes.cxx \
SMDS_FaceOfEdges.cxx \
SMDS_FaceOfNodes.cxx \
+ SMDS_PolygonalFaceOfNodes.cxx \
SMDS_VolumeTool.cxx
# SMDS_Tria3OfNodes.cxx \
# SMDS_HexahedronOfNodes.cxx
SMDS_IteratorOfElements.hxx \
SMDS_VolumeOfFaces.hxx \
SMDS_VolumeOfNodes.hxx \
+ SMDS_PolyhedralVolumeOfNodes.hxx \
SMDS_FaceOfEdges.hxx \
SMDS_FaceOfNodes.hxx \
+ SMDS_PolygonalFaceOfNodes.hxx \
SMDS_VolumeTool.hxx
# SMDS_Tria3OfNodes.hxx \
# SMDS_HexahedronOfNodes.hxx
#include "SMDS_VolumeOfFaces.hxx"
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_FaceOfEdges.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
#include <algorithm>
#include <map>
}
///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes IDs
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+ const int ID)
+{
+ int nbNodes = nodes_ids.size();
+ std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+ for (int i = 0; i < nbNodes; i++) {
+ nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+ if (!nodes[i]) return NULL;
+ }
+ return SMDS_Mesh::AddPolygonalFaceWithID(nodes, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFaceWithID
+ (std::vector<const SMDS_MeshNode*> nodes,
+ const int ID)
+{
+ SMDS_MeshFace * face;
+
+ if (hasConstructionEdges())
+ {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ }
+ else
+ {
+ face = new SMDS_PolygonalFaceOfNodes(nodes);
+ myFaces.Add(face);
+ }
+
+ if (!registerElement(ID, face)) {
+ RemoveElement(face, false);
+ face = NULL;
+ }
+ return face;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Add a polygon defined by its nodes.
+/// An ID is automatically affected to the created face.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshFace* SMDS_Mesh::AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes)
+{
+ return SMDS_Mesh::AddPolygonalFaceWithID(nodes, myElementIDFactory->GetFreeID());
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh.
+/// @param ID The ID of the new volume
+/// @return The created volume or NULL if an element with this ID already exists
+/// or if input nodes are not found.
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume * SMDS_Mesh::AddPolyhedralVolumeWithID
+ (std::vector<int> nodes_ids,
+ std::vector<int> quantities,
+ const int ID)
+{
+ int nbNodes = nodes_ids.size();
+ std::vector<const SMDS_MeshNode*> nodes (nbNodes);
+ for (int i = 0; i < nbNodes; i++) {
+ nodes[i] = (SMDS_MeshNode *)myNodeIDFactory->MeshElement(nodes_ids[i]);
+ if (!nodes[i]) return NULL;
+ }
+ return SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh.
+/// @param ID The ID of the new volume
+/// @return The created volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolumeWithID
+ (std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities,
+ const int ID)
+{
+ SMDS_MeshVolume* volume;
+ if (hasConstructionFaces()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ } else if (hasConstructionEdges()) {
+ MESSAGE("Error : Not implemented");
+ return NULL;
+ } else {
+ volume = new SMDS_PolyhedralVolumeOfNodes(nodes, quantities);
+ myVolumes.Add(volume);
+ }
+
+ if (!registerElement(ID, volume)) {
+ RemoveElement(volume, false);
+ volume = NULL;
+ }
+ return volume;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Create a new polyhedral volume and add it to the mesh.
+/// @return The created volume
+///////////////////////////////////////////////////////////////////////////////
+
+SMDS_MeshVolume* SMDS_Mesh::AddPolyhedralVolume
+ (std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities)
+{
+ int ID = myElementIDFactory->GetFreeID();
+ SMDS_MeshVolume * v = SMDS_Mesh::AddPolyhedralVolumeWithID(nodes, quantities, ID);
+ if (v == NULL) myElementIDFactory->ReleaseID(ID);
+ return v;
+}
+
+///////////////////////////////////////////////////////////////////////////////
/// Registers element with the given ID, maintains inverse connections
///////////////////////////////////////////////////////////////////////////////
bool SMDS_Mesh::registerElement(int ID, SMDS_MeshElement * element)
}
case SMDSAbs_Face: {
const SMDS_FaceOfNodes* face = dynamic_cast<const SMDS_FaceOfNodes*>( elem );
- if ( face )
+ if ( face ) {
Ok = const_cast<SMDS_FaceOfNodes*>( face )->ChangeNodes( nodes, nbnodes );
+ } else {
+ /// ??? begin
+ const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+ if (face) {
+ Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+ }
+ /// ??? end
+ }
break;
}
+ //case SMDSAbs_PolygonalFace: {
+ // const SMDS_PolygonalFaceOfNodes* face = dynamic_cast<const SMDS_PolygonalFaceOfNodes*>(elem);
+ // if (face) {
+ // Ok = const_cast<SMDS_PolygonalFaceOfNodes*>(face)->ChangeNodes(nodes, nbnodes);
+ // }
+ // break;
+ //}
case SMDSAbs_Volume: {
const SMDS_VolumeOfNodes* vol = dynamic_cast<const SMDS_VolumeOfNodes*>( elem );
if ( vol )
}
//=======================================================================
+//function : ChangePolyhedronNodes
+//purpose : to change nodes of polyhedral volume
+//=======================================================================
+bool SMDS_Mesh::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
+ std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities)
+{
+ if (elem->GetType() != SMDSAbs_Volume) {
+ MESSAGE("WRONG ELEM TYPE");
+ return false;
+ }
+
+ const SMDS_PolyhedralVolumeOfNodes* vol = dynamic_cast<const SMDS_PolyhedralVolumeOfNodes*>(elem);
+ if (!vol) {
+ return false;
+ }
+
+ // keep current nodes of elem
+ set<const SMDS_MeshElement*> oldNodes;
+ SMDS_ElemIteratorPtr itn = elem->nodesIterator();
+ while (itn->more()) {
+ oldNodes.insert(itn->next());
+ }
+
+ // change nodes
+ bool Ok = const_cast<SMDS_PolyhedralVolumeOfNodes*>(vol)->ChangeNodes(nodes, quantities);
+ if (!Ok) {
+ return false;
+ }
+
+ // update InverseElements
+
+ // AddInverseElement to new nodes
+ int nbnodes = nodes.size();
+ for (int i = 0; i < nbnodes; i++) {
+ if (oldNodes.find(nodes[i]) == oldNodes.end()) {
+ // new node
+ const_cast<SMDS_MeshNode*>(nodes[i])->AddInverseElement(elem);
+ } else {
+ // remove from oldNodes a node that remains in elem
+ oldNodes.erase(nodes[i]);
+ }
+ }
+
+ // RemoveInverseElement from the nodes removed from elem
+ set<const SMDS_MeshElement*>::iterator it;
+ for (it = oldNodes.begin(); it != oldNodes.end(); it++) {
+ SMDS_MeshNode * n = static_cast<SMDS_MeshNode *>
+ (const_cast<SMDS_MeshElement *>( *it ));
+ n->RemoveInverseElement(elem);
+ }
+
+ return Ok;
+}
+
+//=======================================================================
//function : FindEdge
//purpose :
//=======================================================================
}
//=======================================================================
+//function : FindFace
+//purpose : find polygon
+//=======================================================================
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<int> nodes_ids) const
+{
+ int nbnodes = nodes_ids.size();
+ std::vector<const SMDS_MeshNode *> poly_nodes (nbnodes);
+ for (int inode = 0; inode < nbnodes; inode++) {
+ const SMDS_MeshNode * node = FindNode(nodes_ids[inode]);
+ if (node == NULL) return NULL;
+ }
+ return FindFace(poly_nodes);
+}
+
+const SMDS_MeshFace* SMDS_Mesh::FindFace (std::vector<const SMDS_MeshNode *> nodes)
+{
+ int nbNodes = nodes.size();
+ if (nbNodes < 1) return NULL;
+
+ bool isFound = true;
+ const SMDS_MeshFace * face;
+ set<const SMDS_MeshFace *> faces;
+
+ for (int inode = 0; inode < nbNodes && isFound; inode++) {
+ set<const SMDS_MeshFace *> new_faces;
+
+ SMDS_ElemIteratorPtr itF = nodes[inode]->facesIterator();
+ while (itF->more()) {
+ face = static_cast<const SMDS_MeshFace *>(itF->next());
+ if (face->NbNodes() == nbNodes) {
+ if (inode == 0 || faces.find(face) != faces.end()) {
+ new_faces.insert(face);
+ }
+ }
+ }
+ faces = new_faces;
+ if (new_faces.size() == 0) {
+ isFound = false;
+ }
+ }
+
+ if (isFound)
+ return face;
+
+ return NULL;
+}
+
+//=======================================================================
//function : DumpNodes
//purpose :
//=======================================================================
// get finite elements built on elem
set<const SMDS_MeshElement*> * s1;
if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge ||
- !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face)
+ !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face ||
+ elem->GetType() == SMDSAbs_Volume)
{
s1 = new set<const SMDS_MeshElement*>();
s1->insert(elem);
ID += deltaID;
}
}
-
const SMDS_MeshFace * f5,
const SMDS_MeshFace * f6);
+ virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<int> nodes_ids,
+ const int ID);
+
+ virtual SMDS_MeshFace* AddPolygonalFaceWithID (std::vector<const SMDS_MeshNode*> nodes,
+ const int ID);
+
+ virtual SMDS_MeshFace* AddPolygonalFace (std::vector<const SMDS_MeshNode*> nodes);
+
+ virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
+ (std::vector<int> nodes_ids,
+ std::vector<int> quantities,
+ const int ID);
+
+ virtual SMDS_MeshVolume* AddPolyhedralVolumeWithID
+ (std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities,
+ const int ID);
+
+ virtual SMDS_MeshVolume* AddPolyhedralVolume
+ (std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities);
+
virtual void RemoveElement(const SMDS_MeshElement * elem,
std::list<const SMDS_MeshElement *>& removedElems,
std::list<const SMDS_MeshElement *>& removedNodes,
static bool ChangeElementNodes(const SMDS_MeshElement * elem,
const SMDS_MeshNode * nodes[],
const int nbnodes);
+ static bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
+ std::vector<const SMDS_MeshNode*> nodes,
+ std::vector<int> quantities);
virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
// Renumber all nodes or elements.
const SMDS_MeshNode *n2,
const SMDS_MeshNode *n3,
const SMDS_MeshNode *n4);
+
+ const SMDS_MeshFace *FindFace(std::vector<int> nodes_ids) const;
+ static const SMDS_MeshFace* FindFace(std::vector<const SMDS_MeshNode *> nodes);
+
int MaxNodeID() const;
int MinNodeID() const;
int MaxElementID() const;
///Return the type of the current element
virtual SMDSAbs_ElementType GetType() const = 0;
+ virtual bool IsPoly() const { return false; };
+
friend std::ostream & operator <<(std::ostream & OS, const SMDS_MeshElement *);
friend bool SMDS_MeshElementIDFactory::BindID(int ID,SMDS_MeshElement*elem);
// the type of the group is determined by the first element added
if (myElements.empty()) myType = theElem->GetType();
else if (theElem->GetType() != myType)
- MESSAGE("SMDS_MeshGroup::Add : Type Mismatch");
+ MESSAGE("SMDS_MeshGroup::Add : Type Mismatch "<<theElem->GetType()<<"!="<<myType);
myElements.insert(theElem);
}
if (myPoolOfID.empty()) return ++myMaxID;
else
{
- int ID = myPoolOfID.top();
- myPoolOfID.pop();
+ set<int>::iterator i = myPoolOfID.begin();
+ int ID = *i;//myPoolOfID.top();
+ myPoolOfID.erase( i );//myPoolOfID.pop();
return ID;
}
}
//=======================================================================
void SMDS_MeshIDFactory::ReleaseID(const int ID)
{
- if (ID > 0 && ID < myMaxID) myPoolOfID.push(ID);
+ if ( ID > 0 )
+ {
+ if ( ID < myMaxID )
+ {
+ myPoolOfID.insert(ID);
+ }
+ else if ( ID == myMaxID )
+ {
+ --myMaxID;
+ if ( !myPoolOfID.empty() ) // assure that myMaxID is not in myPoolOfID
+ {
+ set<int>::iterator i = --myPoolOfID.end();
+ while ( i != myPoolOfID.begin() && myMaxID == *i ) {
+ --myMaxID; --i;
+ }
+ if ( myMaxID == *i )
+ --myMaxID; // begin of myPoolOfID reached
+ else
+ ++i;
+ myPoolOfID.erase( i, myPoolOfID.end() );
+ }
+ }
+ }
}
#define _SMDS_MeshIDFactory_HeaderFile
#include "SMDS_MeshObject.hxx"
-#include <stack>
+#include <set>
class SMDS_MeshIDFactory:public SMDS_MeshObject
protected:
SMDS_MeshIDFactory();
int myMaxID;
- std::stack<int> myPoolOfID;
+ std::set<int> myPoolOfID;
};
#endif
--- /dev/null
+// SMESH SMDS : implementaion of Salome mesh data structure
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_PolygonalFaceOfNodes.hxx"
+
+#include "SMDS_IteratorOfElements.hxx"
+//#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+using namespace std;
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+SMDS_PolygonalFaceOfNodes::SMDS_PolygonalFaceOfNodes
+ (std::vector<const SMDS_MeshNode *> nodes)
+{
+ myNodes = nodes;
+}
+
+//=======================================================================
+//function : GetType
+//purpose :
+//=======================================================================
+SMDSAbs_ElementType SMDS_PolygonalFaceOfNodes::GetType() const
+{
+ return SMDSAbs_Face;
+ //return SMDSAbs_PolygonalFace;
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose :
+//=======================================================================
+bool SMDS_PolygonalFaceOfNodes::ChangeNodes (std::vector<const SMDS_MeshNode *> nodes)
+{
+ if (nodes.size() < 3)
+ return false;
+
+ myNodes = nodes;
+
+ return true;
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose : to support the same interface, as SMDS_FaceOfNodes
+//=======================================================================
+bool SMDS_PolygonalFaceOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[],
+ const int nbNodes)
+{
+ if (nbNodes < 3)
+ return false;
+
+ myNodes.resize(nbNodes);
+ int i = 0;
+ for (; i < nbNodes; i++) {
+ myNodes[i] = nodes[i];
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : NbNodes
+//purpose :
+//=======================================================================
+int SMDS_PolygonalFaceOfNodes::NbNodes() const
+{
+ return myNodes.size();
+}
+
+//=======================================================================
+//function : NbEdges
+//purpose :
+//=======================================================================
+int SMDS_PolygonalFaceOfNodes::NbEdges() const
+{
+ return NbNodes();
+}
+
+//=======================================================================
+//function : NbFaces
+//purpose :
+//=======================================================================
+int SMDS_PolygonalFaceOfNodes::NbFaces() const
+{
+ return 1;
+}
+
+//=======================================================================
+//function : Print
+//purpose :
+//=======================================================================
+void SMDS_PolygonalFaceOfNodes::Print(ostream & OS) const
+{
+ OS << "polygonal face <" << GetID() << " > : ";
+ int i, nbNodes = myNodes.size();
+ for (i = 0; i < nbNodes - 1; i++)
+ OS << myNodes[i] << ",";
+ OS << myNodes[i] << ") " << endl;
+}
+
+//=======================================================================
+//function : elementsIterator
+//purpose :
+//=======================================================================
+class SMDS_PolygonalFaceOfNodes_MyIterator:public SMDS_ElemIterator
+{
+ //const SMDS_MeshNode* const *mySet;
+ const std::vector<const SMDS_MeshNode *> mySet;
+ //int myLength;
+ int index;
+ public:
+ //SMDS_PolygonalFaceOfNodes_MyIterator(const SMDS_MeshNode* const *s, int l):
+ // mySet(s),myLength(l),index(0) {}
+ SMDS_PolygonalFaceOfNodes_MyIterator(const std::vector<const SMDS_MeshNode *> s):
+ mySet(s),index(0) {}
+
+ bool more()
+ {
+ return index < mySet.size();
+ }
+
+ const SMDS_MeshElement* next()
+ {
+ index++;
+ return mySet[index-1];
+ }
+};
+
+SMDS_ElemIteratorPtr SMDS_PolygonalFaceOfNodes::elementsIterator
+ (SMDSAbs_ElementType type) const
+{
+ switch(type)
+ {
+ case SMDSAbs_Face:
+ return SMDS_MeshElement::elementsIterator(SMDSAbs_Face);
+ case SMDSAbs_Node:
+ return SMDS_ElemIteratorPtr(new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes));
+ case SMDSAbs_Edge:
+ MESSAGE("Error : edge iterator for SMDS_PolygonalFaceOfNodes not implemented");
+ break;
+ default:
+ return SMDS_ElemIteratorPtr
+ (new SMDS_IteratorOfElements
+ (this,type,SMDS_ElemIteratorPtr
+ (new SMDS_PolygonalFaceOfNodes_MyIterator(myNodes))));
+ }
+ return SMDS_ElemIteratorPtr();
+}
--- /dev/null
+// SMESH SMDS : implementaion of Salome mesh data structure
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifndef _SMDS_PolygonalFaceOfNodes_HeaderFile
+#define _SMDS_PolygonalFaceOfNodes_HeaderFile
+
+#include "SMDS_MeshFace.hxx"
+//#include "SMDS_FaceOfNodes.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_Iterator.hxx"
+
+#include <iostream>
+
+//class SMDS_PolygonalFaceOfNodes:public SMDS_FaceOfNodes
+class SMDS_PolygonalFaceOfNodes:public SMDS_MeshFace
+{
+ public:
+ SMDS_PolygonalFaceOfNodes (std::vector<const SMDS_MeshNode *> nodes);
+
+ virtual SMDSAbs_ElementType GetType() const;
+ virtual bool IsPoly() const { return true; };
+
+ bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes);
+
+ bool ChangeNodes (const SMDS_MeshNode* nodes[],
+ const int nbNodes);
+ // to support the same interface, as SMDS_FaceOfNodes
+
+ virtual int NbNodes() const;
+ virtual int NbEdges() const;
+ virtual int NbFaces() const;
+
+ virtual void Print (std::ostream & OS) const;
+
+ protected:
+ virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+
+ private:
+ std::vector<const SMDS_MeshNode *> myNodes;
+};
+
+#endif
--- /dev/null
+// SMESH SMDS : implementaion of Salome mesh data structure
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+
+#ifdef _MSC_VER
+#pragma warning(disable:4786)
+#endif
+
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "utilities.h"
+
+#include <set>
+
+using namespace std;
+
+//=======================================================================
+//function : Constructor
+//purpose : Create a volume of many faces
+//=======================================================================
+SMDS_PolyhedralVolumeOfNodes::SMDS_PolyhedralVolumeOfNodes
+ (std::vector<const SMDS_MeshNode *> nodes,
+ std::vector<int> quantities)
+: SMDS_VolumeOfNodes(NULL, NULL, NULL, NULL)
+{
+ ChangeNodes(nodes, quantities);
+}
+
+//=======================================================================
+//function : GetType
+//purpose :
+//=======================================================================
+SMDSAbs_ElementType SMDS_PolyhedralVolumeOfNodes::GetType() const
+{
+// return SMDSAbs_PolyhedralVolume;
+ return SMDSAbs_Volume;
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose :
+//=======================================================================
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
+ std::vector<int> quantities)
+{
+ myNodesByFaces = nodes;
+ myQuantities = quantities;
+
+ // Init fields of parent class
+ int aNbNodes = 0;
+ std::set<const SMDS_MeshNode *> aSet;
+ int nodes_len = nodes.size();
+ for (int j = 0; j < nodes_len; j++) {
+ if (aSet.find(nodes[j]) == aSet.end()) {
+ aSet.insert(nodes[j]);
+ aNbNodes++;
+ }
+ }
+
+ int k = 0;
+ const SMDS_MeshNode* aNodes [aNbNodes];
+ std::set<const SMDS_MeshNode *>::iterator anIter = aSet.begin();
+ for (; anIter != aSet.end(); anIter++, k++) {
+ aNodes[k] = *anIter;
+ }
+
+ //SMDS_VolumeOfNodes::ChangeNodes(aNodes, aNbNodes);
+ delete [] myNodes;
+ //myNbNodes = nodes.size();
+ myNbNodes = aNbNodes;
+ myNodes = new const SMDS_MeshNode* [myNbNodes];
+ for (int i = 0; i < myNbNodes; i++) {
+ //myNodes[i] = nodes[i];
+ myNodes[i] = aNodes[i];
+ }
+
+ return true;
+}
+
+//=======================================================================
+//function : NbEdges
+//purpose :
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbEdges() const
+{
+ int nbEdges = 0;
+
+ for (int ifa = 0; ifa < myQuantities.size(); ifa++) {
+ nbEdges += myQuantities[ifa];
+ }
+ nbEdges /= 2;
+
+ return nbEdges;
+}
+
+//=======================================================================
+//function : NbFaces
+//purpose :
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbFaces() const
+{
+ return myQuantities.size();
+}
+
+//=======================================================================
+//function : NbFaceNodes
+//purpose :
+//=======================================================================
+int SMDS_PolyhedralVolumeOfNodes::NbFaceNodes (const int face_ind) const
+{
+ if (face_ind < 1 || myQuantities.size() < face_ind)
+ return 0;
+ return myQuantities[face_ind - 1];
+}
+
+//=======================================================================
+//function : GetFaceNode
+//purpose :
+//=======================================================================
+const SMDS_MeshNode* SMDS_PolyhedralVolumeOfNodes::GetFaceNode (const int face_ind,
+ const int node_ind) const
+{
+ if (node_ind < 1 || NbFaceNodes(face_ind) < node_ind)
+ return NULL;
+
+ int i, first_node = 0;
+ for (i = 0; i < face_ind - 1; i++) {
+ first_node += myQuantities[i];
+ }
+
+ return myNodesByFaces[first_node + node_ind - 1];
+}
+
+//=======================================================================
+//function : Print
+//purpose :
+//=======================================================================
+void SMDS_PolyhedralVolumeOfNodes::Print (ostream & OS) const
+{
+ OS << "polyhedral volume <" << GetID() << "> : ";
+
+ int faces_len = myQuantities.size();
+ //int nodes_len = myNodesByFaces.size();
+ int cur_first_node = 0;
+
+ int i, j;
+ for (i = 0; i < faces_len; i++) {
+ OS << "face_" << i << " (";
+ for (j = 0; j < myQuantities[i] - 1; j++) {
+ OS << myNodesByFaces[cur_first_node + j] << ",";
+ }
+ OS << myNodesByFaces[cur_first_node + j] << ") ";
+ cur_first_node += myQuantities[i];
+ }
+}
+
+//=======================================================================
+//function : ChangeNodes
+//purpose : usage disabled
+//=======================================================================
+bool SMDS_PolyhedralVolumeOfNodes::ChangeNodes (const SMDS_MeshNode* nodes[],
+ const int nbNodes)
+{
+ return false;
+}
--- /dev/null
+// SMESH SMDS : implementaion of Salome mesh data structure
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+//
+//
+//
+// File : SMDS_PolyhedralVolumeOfNodes.hxx
+// Module : SMESH
+
+#ifndef _SMDS_PolyhedralVolumeOfNodes_HeaderFile
+#define _SMDS_PolyhedralVolumeOfNodes_HeaderFile
+
+#include "SMDS_VolumeOfNodes.hxx"
+
+class SMDS_PolyhedralVolumeOfNodes:public SMDS_VolumeOfNodes
+{
+ public:
+ SMDS_PolyhedralVolumeOfNodes (std::vector<const SMDS_MeshNode *> nodes,
+ std::vector<int> quantities);
+
+ //virtual ~SMDS_PolyhedralVolumeOfNodes();
+
+ virtual SMDSAbs_ElementType GetType() const;
+ virtual bool IsPoly() const { return true; };
+
+ bool ChangeNodes (std::vector<const SMDS_MeshNode *> nodes,
+ std::vector<int> quantities);
+
+ //virtual int NbNodes() const;
+ virtual int NbEdges() const;
+ virtual int NbFaces() const;
+
+ int NbFaceNodes (const int face_ind) const;
+ // 1 <= face_ind <= NbFaces()
+
+ const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const;
+ // 1 <= face_ind <= NbFaces()
+ // 1 <= node_ind <= NbFaceNodes()
+
+ virtual void Print (std::ostream & OS) const;
+
+ protected:
+ //virtual SMDS_ElemIteratorPtr elementsIterator (SMDSAbs_ElementType type) const;
+
+ private:
+ // usage disabled
+ bool ChangeNodes (const SMDS_MeshNode* nodes[],
+ const int nbNodes);
+
+ private:
+ std::vector<const SMDS_MeshNode *> myNodesByFaces;
+ std::vector<int> myQuantities;
+};
+
+#endif
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+
+#include "utilities.h"
+
#include <map>
#include <float.h>
#include <math.h>
SMDS_VolumeTool::SMDS_VolumeTool ()
: myVolume( 0 ),
+ myPolyedre( 0 ),
myVolForward( true ),
myNbFaces( 0 ),
myVolumeNbNodes( 0 ),
- myExternalFaces( false )
+ myVolumeNodes( NULL ),
+ myExternalFaces( false ),
+ myFaceNbNodes( 0 ),
+ myCurFace( -1 ),
+ myFaceNodeIndices( NULL ),
+ myFaceNodes( NULL )
{
}
+
//=======================================================================
//function : SMDS_VolumeTool
//purpose :
//=======================================================================
SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
- : myExternalFaces( false )
+ : myVolume( 0 ),
+ myPolyedre( 0 ),
+ myVolForward( true ),
+ myNbFaces( 0 ),
+ myVolumeNbNodes( 0 ),
+ myVolumeNodes( NULL ),
+ myExternalFaces( false ),
+ myFaceNbNodes( 0 ),
+ myCurFace( -1 ),
+ myFaceNodeIndices( NULL ),
+ myFaceNodes( NULL )
{
Set( theVolume );
}
SMDS_VolumeTool::~SMDS_VolumeTool()
{
+ if (myVolumeNodes != NULL) {
+ delete [] myVolumeNodes;
+ myVolumeNodes = NULL;
+ }
+ if (myFaceNodes != NULL) {
+ delete [] myFaceNodes;
+ myFaceNodes = NULL;
+ }
}
//=======================================================================
bool SMDS_VolumeTool::Set (const SMDS_MeshElement* theVolume)
{
myVolume = 0;
+ myPolyedre = 0;
+
myVolForward = true;
- myCurFace = -1;
- myVolumeNbNodes = 0;
myNbFaces = 0;
+ myVolumeNbNodes = 0;
+ if (myVolumeNodes != NULL) {
+ delete [] myVolumeNodes;
+ myVolumeNodes = NULL;
+ }
+
+ myExternalFaces = false;
+ myFaceNbNodes = 0;
+
+ myCurFace = -1;
+ myFaceNodeIndices = NULL;
+ if (myFaceNodes != NULL) {
+ delete [] myFaceNodes;
+ myFaceNodes = NULL;
+ }
+
if ( theVolume && theVolume->GetType() == SMDSAbs_Volume )
{
+ myVolume = theVolume;
+
+ myNbFaces = theVolume->NbFaces();
myVolumeNbNodes = theVolume->NbNodes();
- switch ( myVolumeNbNodes ) {
- case 4:
- case 5:
- case 6:
- case 8:
- {
- myVolume = theVolume;
- myNbFaces = theVolume->NbFaces();
-
- // set volume nodes
- int iNode = 0;
- SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
- while ( nodeIt->more() )
- myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
-
- // nb nodes in each face
- if ( myVolumeNbNodes == 4 )
- myFaceNbNodes = Tetra_nbN;
- else if ( myVolumeNbNodes == 5 )
- myFaceNbNodes = Pyramid_nbN;
- else if ( myVolumeNbNodes == 6 )
- myFaceNbNodes = Penta_nbN;
- else
- myFaceNbNodes = Hexa_nbN;
-
- // define volume orientation
- XYZ botNormal;
- GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
- const SMDS_MeshNode* topNode = myVolumeNodes[ myVolumeNbNodes - 1 ];
- const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ];
- XYZ upDir (topNode->X() - botNode->X(),
- topNode->Y() - botNode->Y(),
- topNode->Z() - botNode->Z() );
- myVolForward = ( botNormal.Dot( upDir ) < 0 );
- break;
+
+ // set volume nodes
+ int iNode = 0;
+ myVolumeNodes = new const SMDS_MeshNode* [myVolumeNbNodes];
+ SMDS_ElemIteratorPtr nodeIt = myVolume->nodesIterator();
+ while ( nodeIt->more() ) {
+ myVolumeNodes[ iNode++ ] = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
}
- default: myVolume = 0;
+
+ if (myVolume->IsPoly()) {
+ myPolyedre = static_cast<const SMDS_PolyhedralVolumeOfNodes*>( myVolume );
+ if (!myPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ return false;
+ }
+ } else {
+ switch ( myVolumeNbNodes ) {
+ case 4:
+ case 5:
+ case 6:
+ case 8: {
+ // define volume orientation
+ XYZ botNormal;
+ GetFaceNormal( 0, botNormal.x, botNormal.y, botNormal.z );
+ const SMDS_MeshNode* topNode = myVolumeNodes[ myVolumeNbNodes - 1 ];
+ const SMDS_MeshNode* botNode = myVolumeNodes[ 0 ];
+ XYZ upDir (topNode->X() - botNode->X(),
+ topNode->Y() - botNode->Y(),
+ topNode->Z() - botNode->Z() );
+ myVolForward = ( botNormal.Dot( upDir ) < 0 );
+ break;
+ }
+ default:
+ break;
+ }
}
}
return ( myVolume != 0 );
}
//=======================================================================
-//function : GetInverseNodes
-//purpose : Return nodes vector of an inverse volume
+//function : Inverse
+//purpose : Inverse volume
//=======================================================================
#define SWAP_NODES(nodes,i1,i2) \
{
if ( !myVolume ) return;
+ if (myVolume->IsPoly()) {
+ MESSAGE("Warning: attempt to inverse polyhedral volume");
+ return;
+ }
+
myVolForward = !myVolForward;
myCurFace = -1;
int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
{
- if ( !setFace( faceIndex ))
- return 0;
- return myFaceNbNodes[ faceIndex ];
+ if ( !setFace( faceIndex ))
+ return 0;
+ return myFaceNbNodes;
}
//=======================================================================
const int* SMDS_VolumeTool::GetFaceNodesIndices( int faceIndex )
{
+ if (myVolume->IsPoly()) {
+ MESSAGE("Warning: attempt to obtain FaceNodesIndices of polyhedral volume");
+ return NULL;
+ }
if ( !setFace( faceIndex ))
return 0;
return myFaceNodeIndices;
return false;
theFaceNodes.clear();
- int iNode, nbNode = myFaceNbNodes[ faceIndex ];
+ int iNode, nbNode = myFaceNbNodes;
for ( iNode = 0; iNode < nbNode; iNode++ )
theFaceNodes.insert( myFaceNodes[ iNode ]);
-
+
return true;
}
if ( myExternalFaces || !myVolume )
return true;
+ if (myVolume->IsPoly()) {
+ XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
+ GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
+ GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
+ XYZ insideVec (baryCenter - p0);
+ if (insideVec.Dot(aNormal) > 0)
+ return false;
+ return true;
+ }
+
switch ( myVolumeNbNodes ) {
case 4:
case 5:
return true;
}
-
//=======================================================================
//function : GetFaceArea
//purpose : Return face area
double SMDS_VolumeTool::GetFaceArea( int faceIndex )
{
+ if (myVolume->IsPoly()) {
+ MESSAGE("Warning: attempt to obtain area of a face of polyhedral volume");
+ return 0;
+ }
+
if ( !setFace( faceIndex ))
return 0;
XYZ aVec13( p3 - p1 );
double area = aVec12.Crossed( aVec13 ).Magnitude() * 0.5;
- if ( myFaceNbNodes[ faceIndex ] == 4 ) {
+ if ( myFaceNbNodes == 4 ) {
XYZ p4 ( myFaceNodes[3] );
XYZ aVec14( p4 - p1 );
area += aVec14.Crossed( aVec13 ).Magnitude() * 0.5;
int SMDS_VolumeTool::GetOppFaceIndex( int faceIndex ) const
{
int ind = -1;
+ if (myVolume->IsPoly()) {
+ MESSAGE("Warning: attempt to obtain opposite face on polyhedral volume");
+ return ind;
+ }
+
if ( faceIndex >= 0 && faceIndex < NbFaces() ) {
switch ( myVolumeNbNodes ) {
case 6:
if ( faceIndex == 0 || faceIndex == 1 )
ind = 1 - faceIndex;
- break;
+ break;
case 8:
ind = faceIndex + ( faceIndex % 2 ? -1 : 1 );
break;
if ( !myVolume )
return false;
+ if (myVolume->IsPoly()) {
+ if (!myPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ return false;
+ }
+ bool isLinked = false;
+ int iface;
+ for (iface = 1; iface <= myNbFaces && !isLinked; iface++) {
+ int inode, nbFaceNodes = myPolyedre->NbFaceNodes(iface);
+
+ for (inode = 1; inode <= nbFaceNodes && !isLinked; inode++) {
+ const SMDS_MeshNode* curNode = myPolyedre->GetFaceNode(iface, inode);
+
+ if (curNode == theNode1 || curNode == theNode2) {
+ int inextnode = (inode == nbFaceNodes) ? 1 : inode + 1;
+ const SMDS_MeshNode* nextNode = myPolyedre->GetFaceNode(iface, inextnode);
+
+ if ((curNode == theNode1 && nextNode == theNode2) ||
+ (curNode == theNode2 && nextNode == theNode1)) {
+ isLinked = true;
+ }
+ }
+ }
+ }
+ return isLinked;
+ }
+
// find nodes indices
int i1 = -1, i2 = -1;
for ( int i = 0; i < myVolumeNbNodes; i++ ) {
bool SMDS_VolumeTool::IsLinked (const int theNode1Index,
const int theNode2Index) const
{
+ if (myVolume->IsPoly()) {
+ return IsLinked(myVolumeNodes[theNode1Index], myVolumeNodes[theNode2Index]);
+ }
+
int minInd = theNode1Index < theNode2Index ? theNode1Index : theNode2Index;
int maxInd = theNode1Index < theNode2Index ? theNode2Index : theNode1Index;
return -1;
}
-
//=======================================================================
//function : IsFreeFace
//purpose : check that only one volume is build on the face nodes
bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
{
const int free = true;
- if ( !setFace( faceIndex ))
+
+ if (!setFace( faceIndex ))
return !free;
const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
- int nbFaceNodes = NbFaceNodes( faceIndex );
+ int nbFaceNodes = myFaceNbNodes;
// evaluate nb of face nodes shared by other volume
int maxNbShared = -1;
// check traingle parts 1 & 3
if ( isShared[1] && isShared[3] )
return !free; // is not free
- // check traingle parts 0 & 2;
+ // check triangle parts 0 & 2;
// 0 part could not be checked in the loop; check it here
if ( isShared[2] && prevLinkShared &&
volume.IsLinked( nodes[ 0 ], nodes[ 1 ] ) &&
//purpose : Return index of a face formed by theFaceNodes
//=======================================================================
-int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
+/*int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
{
for ( int iFace = 0; iFace < myNbFaces; iFace++ ) {
const int* nodes = GetFaceNodesIndices( iFace );
return iFace;
}
return -1;
-}
+}*/
//=======================================================================
//function : setFace
if ( myCurFace == faceIndex )
return true;
+ myCurFace = -1;
+
if ( faceIndex < 0 || faceIndex >= NbFaces() )
return false;
- // choose face node indices
- switch ( myVolumeNbNodes ) {
- case 4:
- if ( myExternalFaces )
- myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
- else
- myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
- break;
- case 5:
- if ( myExternalFaces )
- myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
- else
- myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
- break;
- case 6:
- if ( myExternalFaces )
- myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
- else
- myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
- break;
- case 8:
- if ( myExternalFaces )
- myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
- else
- myFaceNodeIndices = Hexa_F[ faceIndex ];
- break;
- default: return false;
+ if (myFaceNodes != NULL) {
+ delete [] myFaceNodes;
+ myFaceNodes = NULL;
}
- // set face nodes
- int iNode, nbNode = myFaceNbNodes[ faceIndex ];
- for ( iNode = 0; iNode <= nbNode; iNode++ )
- myFaceNodes[ iNode ] = myVolumeNodes[ myFaceNodeIndices[ iNode ]];
+ if (myVolume->IsPoly()) {
+ if (!myPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ return false;
+ }
+
+ // check orientation
+ bool isGoodOri = true;
+ if (myExternalFaces) {
+ // get natural orientation
+ XYZ aNormal, baryCenter, p0 (myPolyedre->GetFaceNode(faceIndex + 1, 1));
+ SMDS_VolumeTool vTool (myPolyedre);
+ vTool.GetFaceNormal(faceIndex, aNormal.x, aNormal.y, aNormal.z);
+ vTool.GetBaryCenter(baryCenter.x, baryCenter.y, baryCenter.z);
+ XYZ insideVec (baryCenter - p0);
+ if (insideVec.Dot(aNormal) > 0)
+ isGoodOri = false;
+ }
+
+ // set face nodes
+ int iNode;
+ myFaceNbNodes = myPolyedre->NbFaceNodes(faceIndex + 1);
+ myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
+ if (isGoodOri) {
+ for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
+ myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, iNode + 1);
+ } else {
+ for ( iNode = 0; iNode < myFaceNbNodes; iNode++ )
+ myFaceNodes[ iNode ] = myPolyedre->GetFaceNode(faceIndex + 1, myFaceNbNodes - iNode);
+ }
+ myFaceNodes[ myFaceNbNodes ] = myFaceNodes[ 0 ]; // last = first
+
+ } else {
+ // choose face node indices
+ switch ( myVolumeNbNodes ) {
+ case 4:
+ myFaceNbNodes = Tetra_nbN[ faceIndex ];
+ if ( myExternalFaces )
+ myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_RE[ faceIndex ];
+ else
+ myFaceNodeIndices = myVolForward ? Tetra_F[ faceIndex ] : Tetra_R[ faceIndex ];
+ break;
+ case 5:
+ myFaceNbNodes = Pyramid_nbN[ faceIndex ];
+ if ( myExternalFaces )
+ myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_RE[ faceIndex ];
+ else
+ myFaceNodeIndices = myVolForward ? Pyramid_F[ faceIndex ] : Pyramid_R[ faceIndex ];
+ break;
+ case 6:
+ myFaceNbNodes = Penta_nbN[ faceIndex ];
+ if ( myExternalFaces )
+ myFaceNodeIndices = myVolForward ? Penta_FE[ faceIndex ] : Penta_RE[ faceIndex ];
+ else
+ myFaceNodeIndices = myVolForward ? Penta_F[ faceIndex ] : Penta_R[ faceIndex ];
+ break;
+ case 8:
+ myFaceNbNodes = Hexa_nbN[ faceIndex ];
+ if ( myExternalFaces )
+ myFaceNodeIndices = myVolForward ? Hexa_FE[ faceIndex ] : Hexa_RE[ faceIndex ];
+ else
+ myFaceNodeIndices = Hexa_F[ faceIndex ];
+ break;
+ default:
+ return false;
+ }
+
+ // set face nodes
+ myFaceNodes = new const SMDS_MeshNode* [myFaceNbNodes + 1];
+ for ( int iNode = 0; iNode <= myFaceNbNodes; iNode++ )
+ myFaceNodes[ iNode ] = myVolumeNodes[ myFaceNodeIndices[ iNode ]];
+ }
myCurFace = faceIndex;
return true;
}
+
+//=======================================================================
+//function : GetType
+//purpose : return VolumeType by nb of nodes in a volume
+//=======================================================================
+
+SMDS_VolumeTool::VolumeType SMDS_VolumeTool::GetType(int nbNodes)
+{
+ switch ( nbNodes ) {
+ case 4: return TETRA;
+ case 5: return PYRAM;
+ case 6: return PENTA;
+ case 8: return HEXA;
+ default:return UNKNOWN;
+ }
+}
+
+//=======================================================================
+//function : NbFaces
+//purpose : return nb of faces by volume type
+//=======================================================================
+
+int SMDS_VolumeTool::NbFaces( VolumeType type )
+{
+ switch ( type ) {
+ case TETRA: return 4;
+ case PYRAM: return 5;
+ case PENTA: return 5;
+ case HEXA : return 6;
+ default: return 0;
+ }
+}
+
+//=======================================================================
+//function : GetFaceNodesIndices
+//purpose : Return the array of face nodes indices
+// To comfort link iteration, the array
+// length == NbFaceNodes( faceIndex ) + 1 and
+// the last node index == the first one.
+//=======================================================================
+
+const int* SMDS_VolumeTool::GetFaceNodesIndices(VolumeType type,
+ int faceIndex,
+ bool external)
+{
+ switch ( type ) {
+ case TETRA: return Tetra_F[ faceIndex ];
+ case PYRAM: return Pyramid_F[ faceIndex ];
+ case PENTA: return external ? Penta_FE[ faceIndex ] : Penta_F[ faceIndex ];
+ case HEXA: return external ? Hexa_FE[ faceIndex ] : Hexa_F[ faceIndex ];
+ default:;
+ }
+ return 0;
+}
+
+//=======================================================================
+//function : NbFaceNodes
+//purpose : Return number of nodes in the array of face nodes
+//=======================================================================
+
+int SMDS_VolumeTool::NbFaceNodes(VolumeType type,
+ int faceIndex )
+{
+ switch ( type ) {
+ case TETRA: return Tetra_nbN[ faceIndex ];
+ case PYRAM: return Pyramid_nbN[ faceIndex ];
+ case PENTA: return Penta_nbN[ faceIndex ];
+ case HEXA: return Hexa_nbN[ faceIndex ];
+ default:;
+ }
+ return 0;
+}
+
class SMDS_MeshElement;
class SMDS_MeshNode;
+class SMDS_PolyhedralVolumeOfNodes;
#include <vector>
#include <set>
// Return index of a face formed by theFaceNodes.
// Return -1 if a face not found
- int GetFaceIndex( const std::set<int>& theFaceNodesIndices );
+ //int GetFaceIndex( const std::set<int>& theFaceNodesIndices );
// Return index of a face formed by theFaceNodesIndices
// Return -1 if a face not found
+ // ------------------------
+ // static methods for faces
+ // ------------------------
+
+ enum VolumeType { UNKNOWN, TETRA, PYRAM, PENTA, HEXA };
+
+ static VolumeType GetType(int nbNodes);
+ // return VolumeType by nb of nodes in a volume
+
+ static int NbFaces( VolumeType type );
+ // return nb of faces by volume type
+
+ static const int* GetFaceNodesIndices(VolumeType type,
+ int faceIndex,
+ bool external);
+ // Return the array of face nodes indices
+ // To comfort link iteration, the array
+ // length == NbFaceNodes( faceIndex ) + 1 and
+ // the last node index == the first one.
+
+ static int NbFaceNodes(VolumeType type,
+ int faceIndex );
+ // Return number of nodes in the array of face nodes
private:
bool setFace( int faceIndex );
const SMDS_MeshElement* myVolume;
+ const SMDS_PolyhedralVolumeOfNodes* myPolyedre;
+
bool myVolForward;
int myNbFaces;
int myVolumeNbNodes;
- const SMDS_MeshNode* myVolumeNodes[ 8 ];
+ const SMDS_MeshNode** myVolumeNodes;
bool myExternalFaces;
- int* myFaceNodeIndices;
- int* myFaceNbNodes;
- const SMDS_MeshNode* myFaceNodes[ 5 ];
+
int myCurFace;
+ int myFaceNbNodes;
+ int* myFaceNodeIndices;
+ const SMDS_MeshNode** myFaceNodes;
};
#endif
SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Document * myDocument)
: _groupId( 0 )
{
- INFOS("SMESH_Mesh::SMESH_Mesh; this = "<<this);
+ INFOS("SMESH_Mesh::SMESH_Mesh(int localId)");
_id = localId;
_studyId = studyId;
_gen = gen;
SMESH_Mesh::~SMESH_Mesh()
{
- INFOS("SMESH_Mesh::~SMESH_Mesh; this = "<<this);
+ INFOS("SMESH_Mesh::~SMESH_Mesh");
// delete groups
map < int, SMESH_Group * >::iterator itg;
return aSubMesh;
}
+//=============================================================================
+/*!
+ * Get the SMESH_subMesh object implementation. Dont create it, return null
+ * if it does not exist.
+ */
+//=============================================================================
+
+SMESH_subMesh *SMESH_Mesh::GetSubMeshContaining(const int aShapeID)
+throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+
+ map <int, SMESH_subMesh *>::iterator i_sm = _mapSubMesh.find(aShapeID);
+ if (i_sm == _mapSubMesh.end())
+ return NULL;
+ return i_sm->second;
+}
+
//=======================================================================
//function : IsUsedHypothesis
//purpose : Return True if anHyp is used to mesh aSubShape
int Nb = 0;
SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
- while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++;
+ //while(itFaces->more()) if(itFaces->next()->NbNodes()==3) Nb++;
+ const SMDS_MeshFace * curFace;
+ while (itFaces->more()) {
+ curFace = itFaces->next();
+ if (!curFace->IsPoly() && curFace->NbNodes() == 3) Nb++;
+ }
return Nb;
}
int Nb = 0;
SMDS_FaceIteratorPtr itFaces=_myMeshDS->facesIterator();
- while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++;
+ //while(itFaces->more()) if(itFaces->next()->NbNodes()==4) Nb++;
+ const SMDS_MeshFace * curFace;
+ while (itFaces->more()) {
+ curFace = itFaces->next();
+ if (!curFace->IsPoly() && curFace->NbNodes() == 4) Nb++;
+ }
+ return Nb;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// Return the number of polygonal faces in the mesh. This method run in O(n)
+///////////////////////////////////////////////////////////////////////////////
+int SMESH_Mesh::NbPolygons() throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ int Nb = 0;
+ SMDS_FaceIteratorPtr itFaces = _myMeshDS->facesIterator();
+ while (itFaces->more())
+ if (itFaces->next()->IsPoly()) Nb++;
return Nb;
}
Unexpect aCatch(SalomeException);
int Nb = 0;
SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
- while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++;
+ //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==4) Nb++;
+ const SMDS_MeshVolume * curVolume;
+ while (itVolumes->more()) {
+ curVolume = itVolumes->next();
+ if (!curVolume->IsPoly() && curVolume->NbNodes() == 4) Nb++;
+ }
return Nb;
}
Unexpect aCatch(SalomeException);
int Nb = 0;
SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
- while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++;
+ //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==8) Nb++;
+ const SMDS_MeshVolume * curVolume;
+ while (itVolumes->more()) {
+ curVolume = itVolumes->next();
+ if (!curVolume->IsPoly() && curVolume->NbNodes() == 8) Nb++;
+ }
return Nb;
}
Unexpect aCatch(SalomeException);
int Nb = 0;
SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
- while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++;
+ //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==5) Nb++;
+ const SMDS_MeshVolume * curVolume;
+ while (itVolumes->more()) {
+ curVolume = itVolumes->next();
+ if (!curVolume->IsPoly() && curVolume->NbNodes() == 5) Nb++;
+ }
return Nb;
}
Unexpect aCatch(SalomeException);
int Nb = 0;
SMDS_VolumeIteratorPtr itVolumes=_myMeshDS->volumesIterator();
- while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++;
+ //while(itVolumes->more()) if(itVolumes->next()->NbNodes()==6) Nb++;
+ const SMDS_MeshVolume * curVolume;
+ while (itVolumes->more()) {
+ curVolume = itVolumes->next();
+ if (!curVolume->IsPoly() && curVolume->NbNodes() == 6) Nb++;
+ }
+ return Nb;
+}
+
+int SMESH_Mesh::NbPolyhedrons() throw(SALOME_Exception)
+{
+ Unexpect aCatch(SalomeException);
+ int Nb = 0;
+ SMDS_VolumeIteratorPtr itVolumes = _myMeshDS->volumesIterator();
+ while (itVolumes->more())
+ if (itVolumes->next()->IsPoly()) Nb++;
return Nb;
}
if (_mapGroup.find(theGroupID) == _mapGroup.end())
return;
GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
- delete _mapGroup[theGroupID];
_mapGroup.erase (theGroupID);
+ delete _mapGroup[theGroupID];
}
//=============================================================================
SMESH_subMesh *GetSubMeshContaining(const TopoDS_Shape & aSubShape)
throw(SALOME_Exception);
+ SMESH_subMesh *GetSubMeshContaining(const int aShapeID)
+ throw(SALOME_Exception);
+
const list < SMESH_subMesh * >&
GetSubMeshUsingHypothesis(SMESHDS_Hypothesis * anHyp)
throw(SALOME_Exception);
int NbTriangles() throw(SALOME_Exception);
int NbQuadrangles() throw(SALOME_Exception);
+
+ int NbPolygons() throw(SALOME_Exception);
int NbVolumes() throw(SALOME_Exception);
int NbHexas() throw(SALOME_Exception);
int NbPyramids() throw(SALOME_Exception);
-
+
int NbPrisms() throw(SALOME_Exception);
+ int NbPolyhedrons() throw(SALOME_Exception);
+
int NbSubMesh() throw(SALOME_Exception);
int NbGroup() const { return _mapGroup.size(); }
#include "SMESH_MeshEditor.hxx"
-#include "SMESH_ControlsDef.hxx"
-
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_VolumeTool.hxx"
+#include "SMDS_EdgePosition.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_FacePosition.hxx"
+#include "SMDS_SpacePosition.hxx"
+
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
+
#include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx"
#include <gp_Trsf.hxx>
#include <gp_Lin.hxx>
#include <gp_XYZ.hxx>
+#include <gp_XY.hxx>
#include <gp.hxx>
#include <gp_Pln.hxx>
#include <BRep_Tool.hxx>
-#include <SMDS_EdgePosition.hxx>
#include <Geom_Curve.hxx>
-
+#include <Geom_Surface.hxx>
+#include <Geom2d_Curve.hxx>
+#include <Extrema_GenExtPS.hxx>
+#include <Extrema_POnSurf.hxx>
+#include <GeomAdaptor_Surface.hxx>
+#include <ElCLib.hxx>
#include <map>
-#include "utilities.h"
-
using namespace std;
using namespace SMESH::Controls;
}
case SMDSAbs_Volume:
{
- SMDS_VolumeTool vTool;
- if ( !vTool.Set( theElem ))
- return false;
- vTool.Inverse();
- return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() );
+ if (theElem->IsPoly()) {
+ const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+ static_cast<const SMDS_PolyhedralVolumeOfNodes*>( theElem );
+ if (!aPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ return false;
+ }
+
+ int nbFaces = aPolyedre->NbFaces();
+ vector<const SMDS_MeshNode *> poly_nodes;
+ vector<int> quantities (nbFaces);
+
+ // reverse each face of the polyedre
+ for (int iface = 1; iface <= nbFaces; iface++) {
+ int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+ quantities[iface - 1] = nbFaceNodes;
+
+ for (inode = nbFaceNodes; inode >= 1; inode--) {
+ const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
+ poly_nodes.push_back(curNode);
+ }
+ }
+
+ return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities );
+
+ } else {
+ SMDS_VolumeTool vTool;
+ if ( !vTool.Set( theElem ))
+ return false;
+ vTool.Inverse();
+ return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() );
+ }
}
default:;
}
}
-#define DUMPSO(txt) \
+/*#define DUMPSO(txt) \
// cout << txt << endl;
//=============================================================================
-/*!
- *
- */
+//
+//
+//
//=============================================================================
static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
{
// }
return true;
-}
+}*/
//=======================================================================
//function : laplacianSmooth
// connected to that node along an element edge
//=======================================================================
-void laplacianSmooth(SMESHDS_Mesh * theMesh,
- const SMDS_MeshNode* theNode,
- const set<const SMDS_MeshElement*> & theElems,
- const set<const SMDS_MeshNode*> & theFixedNodes)
+void laplacianSmooth(const SMDS_MeshNode* theNode,
+ const Handle(Geom_Surface)& theSurface,
+ map< const SMDS_MeshNode*, gp_XY* >& theUVMap)
{
// find surrounding nodes
+
set< const SMDS_MeshNode* > nodeSet;
SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
- if ( theElems.find( elem ) == theElems.end() )
+ if ( elem->GetType() != SMDSAbs_Face )
continue;
- int i = 0, iNode = 0;
- const SMDS_MeshNode* aNodes [4];
+ // put all nodes in array
+ int nbNodes = 0, iNode = 0;
+ vector< const SMDS_MeshNode*> aNodes( elem->NbNodes() );
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() )
{
- aNodes[ i ] = static_cast<const SMDS_MeshNode*>( itN->next() );
- if ( aNodes[ i ] == theNode )
- iNode = i;
- else
- nodeSet.insert( aNodes[ i ] );
- i++;
- }
- if ( elem->NbNodes() == 4 ) { // remove an opposite node
- iNode += ( iNode < 2 ) ? 2 : -2;
- nodeSet.erase( aNodes[ iNode ]);
+ aNodes[ nbNodes ] = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( aNodes[ nbNodes ] == theNode )
+ iNode = nbNodes; // index of theNode within aNodes
+ nbNodes++;
}
+ // add linked nodes
+ int iAfter = ( iNode + 1 == nbNodes ) ? 0 : iNode + 1;
+ nodeSet.insert( aNodes[ iAfter ]);
+ int iBefore = ( iNode == 0 ) ? nbNodes - 1 : iNode - 1;
+ nodeSet.insert( aNodes[ iBefore ]);
}
// compute new coodrs
+
double coord[] = { 0., 0., 0. };
set< const SMDS_MeshNode* >::iterator nodeSetIt = nodeSet.begin();
for ( ; nodeSetIt != nodeSet.end(); nodeSetIt++ ) {
const SMDS_MeshNode* node = (*nodeSetIt);
- coord[0] += node->X();
- coord[1] += node->Y();
- coord[2] += node->Z();
+ if ( theSurface.IsNull() ) { // smooth in 3D
+ coord[0] += node->X();
+ coord[1] += node->Y();
+ coord[2] += node->Z();
+ }
+ else { // smooth in 2D
+ ASSERT( theUVMap.find( node ) != theUVMap.end() );
+ gp_XY* uv = theUVMap[ node ];
+ coord[0] += uv->X();
+ coord[1] += uv->Y();
+ }
}
- double nbNodes = nodeSet.size();
- theMesh->MoveNode (theNode,
- coord[0]/nbNodes,
- coord[1]/nbNodes,
- coord[2]/nbNodes);
+ int nbNodes = nodeSet.size();
+ if ( !nbNodes )
+ return;
+ coord[0] /= nbNodes;
+ coord[1] /= nbNodes;
+
+ if ( !theSurface.IsNull() ) {
+ ASSERT( theUVMap.find( theNode ) != theUVMap.end() );
+ theUVMap[ theNode ]->SetCoord( coord[0], coord[1] );
+ gp_Pnt p3d = theSurface->Value( coord[0], coord[1] );
+ coord[0] = p3d.X();
+ coord[1] = p3d.Y();
+ coord[2] = p3d.Z();
+ }
+ else
+ coord[2] /= nbNodes;
+
+ // move node
+
+ const_cast< SMDS_MeshNode* >( theNode )->setXYZ(coord[0],coord[1],coord[2]);
}
//=======================================================================
// surrounding elements
//=======================================================================
-void centroidalSmooth(SMESHDS_Mesh * theMesh,
- const SMDS_MeshNode* theNode,
- const set<const SMDS_MeshElement*> & theElems,
- const set<const SMDS_MeshNode*> & theFixedNodes)
+void centroidalSmooth(const SMDS_MeshNode* theNode,
+ const Handle(Geom_Surface)& theSurface,
+ map< const SMDS_MeshNode*, gp_XY* >& theUVMap)
{
gp_XYZ aNewXYZ(0.,0.,0.);
SMESH::Controls::Area anAreaFunc;
double totalArea = 0.;
int nbElems = 0;
+ // compute new XYZ
+
SMDS_ElemIteratorPtr elemIt = theNode->GetInverseElementIterator();
while ( elemIt->more() )
{
const SMDS_MeshElement* elem = elemIt->next();
- if ( theElems.find( elem ) == theElems.end() )
+ if ( elem->GetType() != SMDSAbs_Face )
continue;
-
nbElems++;
gp_XYZ elemCenter(0.,0.,0.);
const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>( itN->next() );
gp_XYZ aP( aNode->X(), aNode->Y(), aNode->Z() );
aNodePoints.push_back( aP );
+ if ( !theSurface.IsNull() ) { // smooth in 2D
+ ASSERT( theUVMap.find( aNode ) != theUVMap.end() );
+ gp_XY* uv = theUVMap[ aNode ];
+ aP.SetCoord( uv->X(), uv->Y(), 0. );
+ }
elemCenter += aP;
}
double elemArea = anAreaFunc.GetValue( aNodePoints );
aNewXYZ += elemCenter * elemArea;
}
aNewXYZ /= totalArea;
- theMesh->MoveNode (theNode,
- aNewXYZ.X(),
- aNewXYZ.Y(),
- aNewXYZ.Z());
+ if ( !theSurface.IsNull() ) {
+ ASSERT( theUVMap.find( theNode ) != theUVMap.end() );
+ theUVMap[ theNode ]->SetCoord( aNewXYZ.X(), aNewXYZ.Y() );
+ aNewXYZ = theSurface->Value( aNewXYZ.X(), aNewXYZ.Y() ).XYZ();
+ }
+
+ // move node
+
+ const_cast< SMDS_MeshNode* >( theNode )->setXYZ(aNewXYZ.X(),aNewXYZ.Y(),aNewXYZ.Z());
+}
+
+//=======================================================================
+//function : getClosestUV
+//purpose : return UV of closest projection
+//=======================================================================
+
+static bool getClosestUV (Extrema_GenExtPS& projector,
+ const gp_Pnt& point,
+ gp_XY & result)
+{
+ projector.Perform( point );
+ if ( projector.IsDone() ) {
+ double u, v, minVal = DBL_MAX;
+ for ( int i = projector.NbExt(); i > 0; i-- )
+ if ( projector.Value( i ) < minVal ) {
+ minVal = projector.Value( i );
+ projector.Point( i ).Parameter( u, v );
+ }
+ result.SetCoord( u, v );
+ return true;
+ }
+ return false;
}
//=======================================================================
set<const SMDS_MeshNode*> & theFixedNodes,
const SmoothMethod theSmoothMethod,
const int theNbIterations,
- double theTgtAspectRatio)
+ double theTgtAspectRatio,
+ const bool the2D)
{
MESSAGE((theSmoothMethod==LAPLACIAN ? "LAPLACIAN" : "CENTROIDAL") << "--::Smooth()");
+ if ( theTgtAspectRatio < 1.0 )
+ theTgtAspectRatio = 1.0;
+
+ SMESH::Controls::AspectRatio aQualityFunc;
+
SMESHDS_Mesh* aMesh = GetMeshDS();
+
if ( theElems.empty() ) {
- // add all faces
+ // add all faces to theElems
SMDS_FaceIteratorPtr fIt = aMesh->facesIterator();
while ( fIt->more() )
theElems.insert( fIt->next() );
}
+ // get all face ids theElems are on
+ set< int > faceIdSet;
+ set< const SMDS_MeshElement* >::iterator itElem;
+ if ( the2D )
+ for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) {
+ int fId = FindShape( *itElem );
+ // check that corresponding submesh exists and a shape is face
+ if (fId &&
+ faceIdSet.find( fId ) == faceIdSet.end() &&
+ aMesh->MeshElements( fId )) {
+ TopoDS_Shape F = aMesh->IndexToShape( fId );
+ if ( !F.IsNull() && F.ShapeType() == TopAbs_FACE )
+ faceIdSet.insert( fId );
+ }
+ }
+ faceIdSet.insert( 0 ); // to smooth elements that are not on any TopoDS_Face
- set<const SMDS_MeshNode*> setMovableNodes;
-
- // Fill setMovableNodes
+ // ===============================================
+ // smooth elements on each TopoDS_Face separately
+ // ===============================================
- map< const SMDS_MeshNode*, int > mapNodeNbFaces;
- set< const SMDS_MeshElement* >::iterator itElem;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+ set< int >::reverse_iterator fId = faceIdSet.rbegin(); // treate 0 fId at the end
+ for ( ; fId != faceIdSet.rend(); ++fId )
{
- const SMDS_MeshElement* elem = (*itElem);
- if ( !elem || elem->GetType() != SMDSAbs_Face )
- continue;
-
- SMDS_ElemIteratorPtr itN = elem->nodesIterator();
- while ( itN->more() ) {
- const SMDS_MeshNode* node =
- static_cast<const SMDS_MeshNode*>( itN->next() );
+ // get face surface and submesh
+ Handle(Geom_Surface) surface;
+ SMESHDS_SubMesh* faceSubMesh = 0;
+ TopoDS_Face face;
+ double fToler2 = 0, vPeriod = 0., uPeriod = 0., f,l;
+ double u1 = 0, u2 = 0, v1 = 0, v2 = 0;
+ bool isUPeriodic = false, isVPeriodic = false;
+ if ( *fId ) {
+ face = TopoDS::Face( aMesh->IndexToShape( *fId ));
+ surface = BRep_Tool::Surface( face );
+ faceSubMesh = aMesh->MeshElements( *fId );
+ fToler2 = BRep_Tool::Tolerance( face );
+ fToler2 *= fToler2 * 10.;
+ isUPeriodic = surface->IsUPeriodic();
+ if ( isUPeriodic )
+ vPeriod = surface->UPeriod();
+ isVPeriodic = surface->IsVPeriodic();
+ if ( isVPeriodic )
+ uPeriod = surface->VPeriod();
+ surface->Bounds( u1, u2, v1, v2 );
+ }
+ // ---------------------------------------------------------
+ // for elements on a face, find movable and fixed nodes and
+ // compute UV for them
+ // ---------------------------------------------------------
+ bool checkBoundaryNodes = false;
+ set<const SMDS_MeshNode*> setMovableNodes;
+ map< const SMDS_MeshNode*, gp_XY* > uvMap, uvMap2;
+ list< gp_XY > listUV; // uvs the 2 uvMaps refer to
+ list< const SMDS_MeshElement* > elemsOnFace;
+
+ Extrema_GenExtPS projector;
+ GeomAdaptor_Surface surfAdaptor;
+ if ( !surface.IsNull() ) {
+ surfAdaptor.Load( surface );
+ projector.Initialize( surfAdaptor, 20,20, 1e-5,1e-5 );
+ }
+ int nbElemOnFace = 0;
+ itElem = theElems.begin();
+ // loop on not yet smoothed elements: look for elems on a face
+ while ( itElem != theElems.end() )
+ {
+ if ( faceSubMesh && nbElemOnFace == faceSubMesh->NbElements() )
+ break; // all elements found
- if ( theFixedNodes.find( node ) != theFixedNodes.end() )
+ const SMDS_MeshElement* elem = (*itElem);
+ if ( !elem || elem->GetType() != SMDSAbs_Face || elem->NbNodes() < 3 ||
+ ( faceSubMesh && !faceSubMesh->Contains( elem ))) {
+ ++itElem;
continue;
+ }
+ elemsOnFace.push_back( elem );
+ theElems.erase( itElem++ );
+ nbElemOnFace++;
- // if node is on edge => it is fixed
- SMDS_PositionPtr aPositionPtr = node->GetPosition();
- if ( aPositionPtr.get() &&
- (aPositionPtr->GetTypeOfPosition() == SMDS_TOP_EDGE ||
- aPositionPtr->GetTypeOfPosition() == SMDS_TOP_VERTEX)) {
- theFixedNodes.insert( node );
+ // get movable nodes of elem
+ const SMDS_MeshNode* node;
+ SMDS_TypeOfPosition posType;
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ node = static_cast<const SMDS_MeshNode*>( itN->next() );
+ const SMDS_PositionPtr& pos = node->GetPosition();
+ posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+ if (posType != SMDS_TOP_EDGE &&
+ posType != SMDS_TOP_VERTEX &&
+ theFixedNodes.find( node ) == theFixedNodes.end())
+ {
+ // 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();
+ bool all = true;
+ if ( faceSubMesh ) {
+ while ( eIt->more() && all ) {
+ const SMDS_MeshElement* e = eIt->next();
+ if ( e->GetType() == SMDSAbs_Face )
+ all = faceSubMesh->Contains( e );
+ }
+ }
+ if ( all )
+ setMovableNodes.insert( node );
+ else
+ checkBoundaryNodes = true;
+ }
+ if ( posType == SMDS_TOP_3DSPACE )
+ checkBoundaryNodes = true;
+ }
+
+ if ( surface.IsNull() )
continue;
+
+ // get nodes to check UV
+ list< const SMDS_MeshNode* > uvCheckNodes;
+ itN = elem->nodesIterator();
+ while ( itN->more() ) {
+ node = static_cast<const SMDS_MeshNode*>( itN->next() );
+ if ( uvMap.find( node ) == uvMap.end() )
+ uvCheckNodes.push_back( node );
+ // add nodes of elems sharing node
+// SMDS_ElemIteratorPtr eIt = node->GetInverseElementIterator();
+// while ( eIt->more() ) {
+// const SMDS_MeshElement* e = eIt->next();
+// if ( e != elem && e->GetType() == SMDSAbs_Face ) {
+// SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+// while ( nIt->more() ) {
+// const SMDS_MeshNode* n =
+// static_cast<const SMDS_MeshNode*>( nIt->next() );
+// if ( uvMap.find( n ) == uvMap.end() )
+// uvCheckNodes.push_back( n );
+// }
+// }
+// }
+ }
+ // check UV on face
+ list< const SMDS_MeshNode* >::iterator n = uvCheckNodes.begin();
+ for ( ; n != uvCheckNodes.end(); ++n )
+ {
+ node = *n;
+ gp_XY uv( 0, 0 );
+ const SMDS_PositionPtr& pos = node->GetPosition();
+ posType = pos.get() ? pos->GetTypeOfPosition() : SMDS_TOP_3DSPACE;
+ // get existing UV
+ switch ( posType ) {
+ case SMDS_TOP_FACE: {
+ SMDS_FacePosition* fPos = ( SMDS_FacePosition* ) pos.get();
+ uv.SetCoord( fPos->GetUParameter(), fPos->GetVParameter() );
+ break;
+ }
+ case SMDS_TOP_EDGE: {
+ TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+ Handle(Geom2d_Curve) pcurve;
+ if ( !S.IsNull() && S.ShapeType() == TopAbs_EDGE )
+ pcurve = BRep_Tool::CurveOnSurface( TopoDS::Edge( S ), face, f,l );
+ if ( !pcurve.IsNull() ) {
+ double u = (( SMDS_EdgePosition* ) pos.get() )->GetUParameter();
+ uv = pcurve->Value( u ).XY();
+ }
+ break;
+ }
+ case SMDS_TOP_VERTEX: {
+ TopoDS_Shape S = aMesh->IndexToShape( pos->GetShapeId() );
+ if ( !S.IsNull() && S.ShapeType() == TopAbs_VERTEX )
+ uv = BRep_Tool::Parameters( TopoDS::Vertex( S ), face ).XY();
+ break;
+ }
+ default:;
+ }
+ // check existing UV
+ bool project = true;
+ gp_Pnt pNode ( node->X(), node->Y(), node->Z() );
+ double dist1 = DBL_MAX, dist2 = 0;
+ if ( posType != SMDS_TOP_3DSPACE ) {
+ dist1 = pNode.SquareDistance( surface->Value( uv.X(), uv.Y() ));
+ project = dist1 > fToler2;
+ }
+ if ( project ) { // compute new UV
+ gp_XY newUV;
+ if ( !getClosestUV( projector, pNode, newUV )) {
+ MESSAGE("Node Projection Failed " << node);
+ }
+ else {
+ if ( isUPeriodic )
+ newUV.SetX( ElCLib::InPeriod( newUV.X(), u1, u2 ));
+ if ( isVPeriodic )
+ newUV.SetY( ElCLib::InPeriod( newUV.Y(), v1, v2 ));
+ // check new UV
+ if ( posType != SMDS_TOP_3DSPACE )
+ dist2 = pNode.SquareDistance( surface->Value( newUV.X(), newUV.Y() ));
+ if ( dist2 < dist1 )
+ uv = newUV;
+ }
+ }
+ // store UV in the map
+ listUV.push_back( uv );
+ uvMap.insert( make_pair( node, &listUV.back() ));
+ }
+ } // loop on not yet smoothed elements
+
+ if ( !faceSubMesh || nbElemOnFace != faceSubMesh->NbElements() )
+ checkBoundaryNodes = true;
+
+ // fix nodes on mesh boundary
+
+ if ( checkBoundaryNodes )
+ {
+ typedef pair<const SMDS_MeshNode*, const SMDS_MeshNode*> TLink;
+ map< TLink, int > linkNbMap; // how many times a link encounters in elemsOnFace
+ map< TLink, int >::iterator link_nb;
+ // put all elements links to linkNbMap
+ list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt )
+ {
+ // put elem nodes in array
+ vector< const SMDS_MeshNode* > nodes;
+ nodes.reserve( (*elemIt)->NbNodes() + 1 );
+ SMDS_ElemIteratorPtr itN = (*elemIt)->nodesIterator();
+ while ( itN->more() )
+ nodes.push_back( static_cast<const SMDS_MeshNode*>( itN->next() ));
+ nodes.push_back( nodes.front() );
+ // loop on elem links: insert them in linkNbMap
+ for ( int iN = 1; iN < nodes.size(); ++iN ) {
+ TLink link;
+ if ( nodes[ iN-1 ]->GetID() < nodes[ iN ]->GetID() )
+ link = make_pair( nodes[ iN-1 ], nodes[ iN ] );
+ else
+ link = make_pair( nodes[ iN ], nodes[ iN-1 ] );
+ link_nb = linkNbMap.find( link );
+ if ( link_nb == linkNbMap.end() )
+ linkNbMap.insert( make_pair ( link, 1 ));
+ else
+ link_nb->second++;
+ }
+ }
+ // remove nodes that are in links encountered only once from setMovableNodes
+ for ( link_nb = linkNbMap.begin(); link_nb != linkNbMap.end(); ++link_nb ) {
+ if ( link_nb->second == 1 ) {
+ setMovableNodes.erase( link_nb->first.first );
+ setMovableNodes.erase( link_nb->first.second );
+ }
}
- // fill mapNodeNbFaces in order to detect fixed boundary nodes
- map<const SMDS_MeshNode*,int>::iterator nodeNbFacesIt =
- mapNodeNbFaces.find ( node );
- if ( nodeNbFacesIt == mapNodeNbFaces.end() )
- mapNodeNbFaces.insert( map<const SMDS_MeshNode*,int>::value_type( node, 1 ));
- else
- (*nodeNbFacesIt).second++;
}
- }
- // put not fixed nodes in setMovableNodes
- map<const SMDS_MeshNode*,int>::iterator nodeNbFacesIt =
- mapNodeNbFaces.begin();
- for ( ; nodeNbFacesIt != mapNodeNbFaces.end(); nodeNbFacesIt++ ) {
- const SMDS_MeshNode* node = (*nodeNbFacesIt).first;
- // a node is on free boundary if it is shared by 1-2 faces
- if ( (*nodeNbFacesIt).second > 2 )
- setMovableNodes.insert( node );
- else
- theFixedNodes.insert( node );
- }
- // SMOOTHING //
+ // -----------------------------------------------------
+ // for nodes on seam edge, compute one more UV ( uvMap2 );
+ // find movable nodes linked to nodes on seam and which
+ // are to be smoothed using the second UV ( uvMap2 )
+ // -----------------------------------------------------
- if ( theTgtAspectRatio < 1.0 )
- theTgtAspectRatio = 1.0;
+ set<const SMDS_MeshNode*> nodesNearSeam; // to smooth using uvMap2
+ if ( !surface.IsNull() )
+ {
+ TopExp_Explorer eExp( face, TopAbs_EDGE );
+ for ( ; eExp.More(); eExp.Next() )
+ {
+ TopoDS_Edge edge = TopoDS::Edge( eExp.Current() );
+ if ( !BRep_Tool::IsClosed( edge, face ))
+ continue;
+ SMESHDS_SubMesh* sm = aMesh->MeshElements( edge );
+ if ( !sm ) continue;
+ // find out which parameter varies for a node on seam
+ double f,l;
+ gp_Pnt2d uv1, uv2;
+ Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f, l );
+ if ( pcurve.IsNull() ) continue;
+ uv1 = pcurve->Value( f );
+ edge.Reverse();
+ pcurve = BRep_Tool::CurveOnSurface( edge, face, f, l );
+ if ( pcurve.IsNull() ) continue;
+ uv2 = pcurve->Value( f );
+ int iPar = Abs( uv1.X() - uv2.X() ) > Abs( uv1.Y() - uv2.Y() ) ? 1 : 2;
+ // assure uv1 < uv2
+ if ( uv1.Coord( iPar ) > uv2.Coord( iPar )) {
+ gp_Pnt2d tmp = uv1; uv1 = uv2; uv2 = tmp;
+ }
+ // get nodes on seam and its vertices
+ list< const SMDS_MeshNode* > seamNodes;
+ SMDS_NodeIteratorPtr nSeamIt = sm->GetNodes();
+ while ( nSeamIt->more() )
+ seamNodes.push_back( nSeamIt->next() );
+ TopExp_Explorer vExp( edge, TopAbs_VERTEX );
+ for ( ; vExp.More(); vExp.Next() ) {
+ sm = aMesh->MeshElements( vExp.Current() );
+ if ( sm ) {
+ nSeamIt = sm->GetNodes();
+ while ( nSeamIt->more() )
+ seamNodes.push_back( nSeamIt->next() );
+ }
+ }
+ // loop on nodes on seam
+ list< const SMDS_MeshNode* >::iterator noSeIt = seamNodes.begin();
+ for ( ; noSeIt != seamNodes.end(); ++noSeIt )
+ {
+ const SMDS_MeshNode* nSeam = *noSeIt;
+ map< const SMDS_MeshNode*, gp_XY* >::iterator n_uv = uvMap.find( nSeam );
+ if ( n_uv == uvMap.end() )
+ continue;
+ // set the first UV
+ n_uv->second->SetCoord( iPar, uv1.Coord( iPar ));
+ // set the second UV
+ listUV.push_back( *n_uv->second );
+ listUV.back().SetCoord( iPar, uv2.Coord( iPar ));
+ if ( uvMap2.empty() )
+ uvMap2 = uvMap; // copy the uvMap contents
+ uvMap2[ nSeam ] = &listUV.back();
+
+ // collect movable nodes linked to ones on seam in nodesNearSeam
+ SMDS_ElemIteratorPtr eIt = nSeam->GetInverseElementIterator();
+ while ( eIt->more() )
+ {
+ const SMDS_MeshElement* e = eIt->next();
+ if ( e->GetType() != SMDSAbs_Face )
+ continue;
+ int nbUseMap1 = 0, nbUseMap2 = 0;
+ SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+ while ( nIt->more() )
+ {
+ const SMDS_MeshNode* n =
+ static_cast<const SMDS_MeshNode*>( nIt->next() );
+ if (n == nSeam ||
+ setMovableNodes.find( n ) == setMovableNodes.end() )
+ continue;
+ // add only nodes being closer to uv2 than to uv1
+ gp_Pnt pMid (0.5 * ( n->X() + nSeam->X() ),
+ 0.5 * ( n->Y() + nSeam->Y() ),
+ 0.5 * ( n->Z() + nSeam->Z() ));
+ gp_XY uv;
+ getClosestUV( projector, pMid, uv );
+ if ( uv.Coord( iPar ) > uvMap[ n ]->Coord( iPar ) ) {
+ nodesNearSeam.insert( n );
+ nbUseMap2++;
+ }
+ else
+ nbUseMap1++;
+ }
+ // for centroidalSmooth all element nodes must
+ // be on one side of a seam
+ if ( theSmoothMethod == CENTROIDAL && nbUseMap1 && nbUseMap2 )
+ {
+ SMDS_ElemIteratorPtr nIt = e->nodesIterator();
+ while ( nIt->more() ) {
+ const SMDS_MeshNode* n =
+ static_cast<const SMDS_MeshNode*>( nIt->next() );
+ setMovableNodes.erase( n );
+ }
+ }
+ }
+ } // loop on nodes on seam
+ } // loop on edge of a face
+ } // if ( !face.IsNull() )
- SMESH::Controls::AspectRatio aQualityFunc;
+ if ( setMovableNodes.empty() ) {
+ MESSAGE( "Face id : " << *fId << " - NO SMOOTHING: no nodes to move!!!");
+ continue; // goto next face
+ }
- for ( int it = 0; it < theNbIterations; it++ )
- {
- Standard_Real maxDisplacement = 0.;
- set<const SMDS_MeshNode*>::iterator movableNodesIt
- = setMovableNodes.begin();
- for ( ; movableNodesIt != setMovableNodes.end(); movableNodesIt++ )
+ // -------------
+ // SMOOTHING //
+ // -------------
+
+ int it = -1;
+ double maxRatio = -1., maxDisplacement = -1.;
+ set<const SMDS_MeshNode*>::iterator nodeToMove;
+ for ( it = 0; it < theNbIterations; it++ )
{
- const SMDS_MeshNode* node = (*movableNodesIt);
- gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() );
+ maxDisplacement = 0.;
+ nodeToMove = setMovableNodes.begin();
+ for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
+ {
+ const SMDS_MeshNode* node = (*nodeToMove);
+ gp_XYZ aPrevPos ( node->X(), node->Y(), node->Z() );
- // smooth
- if ( theSmoothMethod == LAPLACIAN )
- laplacianSmooth( aMesh, node, theElems, theFixedNodes );
- else
- centroidalSmooth( aMesh, node, theElems, theFixedNodes );
+ // smooth
+ bool map2 = ( nodesNearSeam.find( node ) != nodesNearSeam.end() );
+ if ( theSmoothMethod == LAPLACIAN )
+ laplacianSmooth( node, surface, map2 ? uvMap2 : uvMap );
+ else
+ centroidalSmooth( node, surface, map2 ? uvMap2 : uvMap );
- // displacement
- gp_XYZ aNewPos ( node->X(), node->Y(), node->Z() );
- Standard_Real aDispl = (aPrevPos - aNewPos).SquareModulus();
- if ( aDispl > maxDisplacement )
- maxDisplacement = aDispl;
- }
- // no node movement => exit
- if ( maxDisplacement < 1.e-16 ) {
- MESSAGE("-- no node movement -- maxDisplacement: " << maxDisplacement << " it "<< it);
- break;
- }
+ // node displacement
+ gp_XYZ aNewPos ( node->X(), node->Y(), node->Z() );
+ Standard_Real aDispl = (aPrevPos - aNewPos).SquareModulus();
+ if ( aDispl > maxDisplacement )
+ maxDisplacement = aDispl;
+ }
+ // no node movement => exit
+ if ( maxDisplacement < 1.e-16 ) {
+ MESSAGE("-- no node movement --");
+ break;
+ }
+
+ // check elements quality
+ maxRatio = 0;
+ list< const SMDS_MeshElement* >::iterator elemIt = elemsOnFace.begin();
+ for ( ; elemIt != elemsOnFace.end(); ++elemIt )
+ {
+ const SMDS_MeshElement* elem = (*elemIt);
+ if ( !elem || elem->GetType() != SMDSAbs_Face )
+ continue;
+ SMESH::Controls::TSequenceOfXYZ aPoints;
+ if ( aQualityFunc.GetPoints( elem, aPoints )) {
+ double aValue = aQualityFunc.GetValue( aPoints );
+ if ( aValue > maxRatio )
+ maxRatio = aValue;
+ }
+ }
+ if ( maxRatio <= theTgtAspectRatio ) {
+ MESSAGE("-- quality achived --");
+ break;
+ }
+ if (it+1 == theNbIterations) {
+ MESSAGE("-- Iteration limit exceeded --");
+ }
+ } // smoothing iterations
+
+ MESSAGE(" Face id: " << *fId <<
+ " Nb iterstions: " << it <<
+ " Displacement: " << maxDisplacement <<
+ " Aspect Ratio " << maxRatio);
- // check elements quality
- double maxRatio = 0;
- for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
+ // ---------------------------------------
+ // new nodes positions are computed,
+ // record movement in DS and set new UV
+ // ---------------------------------------
+
+ nodeToMove = setMovableNodes.begin();
+ for ( ; nodeToMove != setMovableNodes.end(); nodeToMove++ )
{
- const SMDS_MeshElement* elem = (*itElem);
- if ( !elem || elem->GetType() != SMDSAbs_Face )
- continue;
- SMESH::Controls::TSequenceOfXYZ aPoints;
- if ( aQualityFunc.GetPoints( elem, aPoints )) {
- double aValue = aQualityFunc.GetValue( aPoints );
- if ( aValue > maxRatio )
- maxRatio = aValue;
+ SMDS_MeshNode* node = const_cast< SMDS_MeshNode* > (*nodeToMove);
+ aMesh->MoveNode( node, node->X(), node->Y(), node->Z() );
+ map< const SMDS_MeshNode*, gp_XY* >::iterator node_uv = uvMap.find( node );
+ if ( node_uv != uvMap.end() ) {
+ gp_XY* uv = node_uv->second;
+ node->SetPosition
+ ( SMDS_PositionPtr( new SMDS_FacePosition( *fId, uv->X(), uv->Y() )));
}
}
- if ( maxRatio <= theTgtAspectRatio ) {
- MESSAGE("-- quality achived -- maxRatio " << maxRatio << " it "<< it);
- break;
- }
- if (it+1 == theNbIterations) {
- MESSAGE("-- Iteration limit exceeded --");
- }
- }
+
+ } // loop on face ids
}
//=======================================================================
SMDS_MeshElement* aNewElem = 0;
switch ( nbNodes )
{
+ case 0:
+ return;
case 1: { // NODE
if ( nbSame == 0 )
aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
nextNod[ i0 ], nextNod[ 1 ], nextNod[ i2 ] );
else if ( nbSame == 1 ) // --- pyramid
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
- nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
nextNod[ iSameNode ]);
else // 2 same nodes: --- tetrahedron
else if ( nbSame == 1 ) // --- pyramid + pentahedron
{
- aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
- nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
+ aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iAfterSame ],
+ nextNod[ iAfterSame ], nextNod[ iBeforeSame ],
nextNod[ iSameNode ]);
newElems.push_back( aNewElem );
- aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
- prevNod[ iBeforeSame ], nextNod[ iAfterSame ],
+ aNewElem = aMesh->AddVolume (prevNod[ iAfterSame ], prevNod[ iOpposSame ],
+ prevNod[ iBeforeSame ], nextNod[ iAfterSame ],
nextNod[ iOpposSame ], nextNod[ iBeforeSame ] );
}
else if ( nbSame == 2 ) // pentahedron
if ( prevNod[ iBeforeSame ] == nextNod[ iBeforeSame ] )
// iBeforeSame is same too
aNewElem = aMesh->AddVolume (prevNod[ iBeforeSame ], prevNod[ iOpposSame ],
- nextNod[ iOpposSame ], prevNod[ iSameNode ],
+ nextNod[ iOpposSame ], prevNod[ iSameNode ],
prevNod[ iAfterSame ], nextNod[ iAfterSame ]);
else
// iAfterSame is same too
- aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
+ aNewElem = aMesh->AddVolume (prevNod[ iSameNode ], prevNod[ iBeforeSame ],
nextNod[ iBeforeSame ], prevNod[ iAfterSame ],
prevNod[ iOpposSame ], nextNod[ iOpposSame ]);
}
break;
}
- default:
- return;
+ default: {
+ // realized for extrusion only
+ vector<const SMDS_MeshNode*> polyedre_nodes (nbNodes*2 + 4*nbNodes);
+ vector<int> quantities (nbNodes + 2);
+
+ quantities[0] = nbNodes; // bottom of prism
+ for (int inode = 0; inode < nbNodes; inode++) {
+ polyedre_nodes[inode] = prevNod[inode];
+ }
+
+ quantities[1] = nbNodes; // top of prism
+ for (int inode = 0; inode < nbNodes; inode++) {
+ polyedre_nodes[nbNodes + inode] = nextNod[inode];
+ }
+
+ for (int iface = 0; iface < nbNodes; iface++) {
+ quantities[iface + 2] = 4;
+ int inextface = (iface == nbNodes - 1) ? 0 : iface + 1;
+ polyedre_nodes[2*nbNodes + 4*iface + 0] = prevNod[iface];
+ polyedre_nodes[2*nbNodes + 4*iface + 1] = prevNod[inextface];
+ polyedre_nodes[2*nbNodes + 4*iface + 2] = nextNod[inextface];
+ polyedre_nodes[2*nbNodes + 4*iface + 3] = nextNod[iface];
+ }
+ aNewElem = aMesh->AddPolyhedralVolume (polyedre_nodes, quantities);
+ }
}
if ( aNewElem )
newElems.push_back( aNewElem );
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ] ); break;
case 4:
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] ); break;
+ default:
+ {
+ int nbPolygonNodes = vTool.NbFaceNodes( *ind );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ aMesh->AddPolygonalFace(polygon_nodes);
+ break;
+ }
}
}
// go to the next volume
!aMesh->FindFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ]))
aMesh->AddFace( nodes[ 0 ], nodes[ 1 ], nodes[ 2 ], nodes[ 3 ] );
break;
+ default:
+ {
+ int nbPolygonNodes = lastVol.NbFaceNodes( iF );
+ vector<const SMDS_MeshNode*> polygon_nodes (nbPolygonNodes);
+ for (int inode = 0; inode < nbPolygonNodes; inode++) {
+ polygon_nodes[inode] = nodes[inode];
+ }
+ if (!hasFreeLinks || !aMesh->FindFace(polygon_nodes))
+ aMesh->AddPolygonalFace(polygon_nodes);
+ }
+ break;
}
}
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
- // check if a node has been already transormed
+ // check if a node has been already transformed
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
if (nodeMap.find( node ) != nodeMap.end() )
const SMDS_MeshNode * newNode = node;
if ( theCopy )
newNode = aMesh->AddNode( coord[0], coord[1], coord[2] );
- else
+ else {
aMesh->MoveNode( node, coord[0], coord[1], coord[2] );
+ // node position on shape becomes invalid
+ const_cast< SMDS_MeshNode* > ( node )->SetPosition
+ ( SMDS_SpacePosition::originSpacePosition() );
+ }
nodeMap.insert( TNodeNodeMap::value_type( node, newNode ));
// keep inverse elements
int nbNodes = elem->NbNodes();
int elemType = elem->GetType();
+ if (elem->IsPoly()) {
+ // Polygon or Polyhedral Volume
+ switch ( elemType ) {
+ case SMDSAbs_Face:
+ {
+ vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
+ int iNode = 0;
+ SMDS_ElemIteratorPtr itN = elem->nodesIterator();
+ while (itN->more()) {
+ const SMDS_MeshNode* node =
+ static_cast<const SMDS_MeshNode*>(itN->next());
+ TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+ if (nodeMapIt == nodeMap.end())
+ break; // not all nodes transformed
+ if (needReverse) {
+ // reverse mirrored faces and volumes
+ poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
+ } else {
+ poly_nodes[iNode] = (*nodeMapIt).second;
+ }
+ iNode++;
+ }
+ if ( iNode != nbNodes )
+ continue; // not all nodes transformed
+
+ if ( theCopy ) {
+ aMesh->AddPolygonalFace(poly_nodes);
+ } else {
+ aMesh->ChangePolygonNodes(elem, poly_nodes);
+ }
+ }
+ break;
+ case SMDSAbs_Volume:
+ {
+ // ATTENTION: Reversing is not yet done!!!
+ const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+ (const SMDS_PolyhedralVolumeOfNodes*) elem;
+ if (!aPolyedre) {
+ MESSAGE("Warning: bad volumic element");
+ continue;
+ }
+
+ vector<const SMDS_MeshNode*> poly_nodes;
+ vector<int> quantities;
+
+ bool allTransformed = true;
+ int nbFaces = aPolyedre->NbFaces();
+ for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
+ int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+ for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
+ const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
+ TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
+ if (nodeMapIt == nodeMap.end()) {
+ allTransformed = false; // not all nodes transformed
+ } else {
+ poly_nodes.push_back((*nodeMapIt).second);
+ }
+ }
+ quantities.push_back(nbFaceNodes);
+ }
+ if ( !allTransformed )
+ continue; // not all nodes transformed
+
+ if ( theCopy ) {
+ aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+ } else {
+ aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+ }
+ }
+ break;
+ default:;
+ }
+ continue;
+ }
+
+ // Regular elements
int* i = index[ FORWARD ];
if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
if ( elemType == SMDSAbs_Face )
}
//=======================================================================
+//function : SimplifyFace
+//purpose :
+//=======================================================================
+int SMESH_MeshEditor::SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
+ vector<const SMDS_MeshNode *>& poly_nodes,
+ vector<int>& quantities) const
+{
+ int nbNodes = faceNodes.size();
+
+ if (nbNodes < 3)
+ return 0;
+
+ set<const SMDS_MeshNode*> nodeSet;
+
+ // get simple seq of nodes
+ const SMDS_MeshNode* simpleNodes[ nbNodes ];
+ int iSimple = 0, nbUnique = 0;
+
+ simpleNodes[iSimple++] = faceNodes[0];
+ nbUnique++;
+ for (int iCur = 1; iCur < nbNodes; iCur++) {
+ if (faceNodes[iCur] != simpleNodes[iSimple - 1]) {
+ simpleNodes[iSimple++] = faceNodes[iCur];
+ if (nodeSet.insert( faceNodes[iCur] ).second)
+ nbUnique++;
+ }
+ }
+ int nbSimple = iSimple;
+ if (simpleNodes[nbSimple - 1] == simpleNodes[0]) {
+ nbSimple--;
+ iSimple--;
+ }
+
+ if (nbUnique < 3)
+ return 0;
+
+ // separate loops
+ int nbNew = 0;
+ bool foundLoop = (nbSimple > nbUnique);
+ while (foundLoop) {
+ foundLoop = false;
+ set<const SMDS_MeshNode*> loopSet;
+ for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) {
+ const SMDS_MeshNode* n = simpleNodes[iSimple];
+ if (!loopSet.insert( n ).second) {
+ foundLoop = true;
+
+ // separate loop
+ int iC = 0, curLast = iSimple;
+ for (; iC < curLast; iC++) {
+ if (simpleNodes[iC] == n) break;
+ }
+ int loopLen = curLast - iC;
+ if (loopLen > 2) {
+ // create sub-element
+ nbNew++;
+ quantities.push_back(loopLen);
+ for (; iC < curLast; iC++) {
+ poly_nodes.push_back(simpleNodes[iC]);
+ }
+ }
+ // shift the rest nodes (place from the first loop position)
+ for (iC = curLast + 1; iC < nbSimple; iC++) {
+ simpleNodes[iC - loopLen] = simpleNodes[iC];
+ }
+ nbSimple -= loopLen;
+ iSimple -= loopLen;
+ }
+ } // for (iSimple = 0; iSimple < nbSimple; iSimple++)
+ } // while (foundLoop)
+
+ if (iSimple > 2) {
+ nbNew++;
+ quantities.push_back(iSimple);
+ for (int i = 0; i < iSimple; i++)
+ poly_nodes.push_back(simpleNodes[i]);
+ }
+
+ return nbNew;
+}
+
+//=======================================================================
//function : MergeNodes
//purpose : In each group, the cdr of nodes are substituted by the first one
// in all elements.
int nbUniqueNodes = nodeSet.size();
if ( nbNodes != nbUniqueNodes ) // some nodes stick
{
+ // Polygons and Polyhedral volumes
+ if (elem->IsPoly()) {
+
+ if (elem->GetType() == SMDSAbs_Face) {
+ // Polygon
+ vector<const SMDS_MeshNode *> face_nodes (nbNodes);
+ int inode = 0;
+ for (; inode < nbNodes; inode++) {
+ face_nodes[inode] = curNodes[inode];
+ }
+
+ vector<const SMDS_MeshNode *> polygons_nodes;
+ vector<int> quantities;
+ int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities);
+
+ if (nbNew > 0) {
+ inode = 0;
+ for (int iface = 0; iface < nbNew - 1; iface++) {
+ int nbNodes = quantities[iface];
+ vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
+ for (int ii = 0; ii < nbNodes; ii++, inode++) {
+ poly_nodes[ii] = polygons_nodes[inode];
+ }
+ SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+ if (aShapeId)
+ aMesh->SetMeshElementOnShape(newElem, aShapeId);
+ }
+ aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]);
+ } else {
+ rmElemIds.push_back(elem->GetID());
+ }
+
+ } else if (elem->GetType() == SMDSAbs_Volume) {
+ // Polyhedral volume
+ if (nbUniqueNodes < 4) {
+ rmElemIds.push_back(elem->GetID());
+ } else {
+ // each face has to be analized in order to check volume validity
+ const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+ static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+ if (aPolyedre) {
+ int nbFaces = aPolyedre->NbFaces();
+
+ vector<const SMDS_MeshNode *> poly_nodes;
+ vector<int> quantities;
+
+ for (int iface = 1; iface <= nbFaces; iface++) {
+ int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+ vector<const SMDS_MeshNode *> faceNodes (nbFaceNodes);
+
+ for (int inode = 1; inode <= nbFaceNodes; inode++) {
+ const SMDS_MeshNode * faceNode = aPolyedre->GetFaceNode(iface, inode);
+ TNodeNodeMap::iterator nnIt = nodeNodeMap.find(faceNode);
+ if (nnIt != nodeNodeMap.end()) { // faceNode sticks
+ faceNode = (*nnIt).second;
+ }
+ faceNodes[inode - 1] = faceNode;
+ }
+
+ SimplifyFace(faceNodes, poly_nodes, quantities);
+ }
+
+ if (quantities.size() > 3) {
+ // to be done: remove coincident faces
+ }
+
+ if (quantities.size() > 3)
+ aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+ else
+ rmElemIds.push_back(elem->GetID());
+
+ } else {
+ rmElemIds.push_back(elem->GetID());
+ }
+ }
+ } else {
+ }
+
+ continue;
+ }
+
+ // Regular elements
switch ( nbNodes ) {
case 2: ///////////////////////////////////// EDGE
isOk = false; break;
} // if ( nbNodes != nbUniqueNodes ) // some nodes stick
- if ( isOk )
- aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes );
- else
+ if ( isOk ) {
+ if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) {
+ // Change nodes of polyedre
+ const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
+ static_cast<const SMDS_PolyhedralVolumeOfNodes*>( elem );
+ if (aPolyedre) {
+ int nbFaces = aPolyedre->NbFaces();
+
+ vector<const SMDS_MeshNode *> poly_nodes;
+ vector<int> quantities (nbFaces);
+
+ for (int iface = 1; iface <= nbFaces; iface++) {
+ int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface);
+ quantities[iface - 1] = nbFaceNodes;
+
+ for (inode = 1; inode <= nbFaceNodes; inode++) {
+ const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode);
+
+ TNodeNodeMap::iterator nnIt = nodeNodeMap.find( curNode );
+ if (nnIt != nodeNodeMap.end()) { // curNode sticks
+ curNode = (*nnIt).second;
+ }
+ poly_nodes.push_back(curNode);
+ }
+ }
+ aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities );
+ }
+ } else {
+ // Change regular element or polygon
+ aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes );
+ }
+ } else {
+ // Remove invalid regular element or invalid polygon
rmElemIds.push_back( elem->GetID() );
+ }
} // loop on elements
const SMDS_MeshNode* theSideFirstNode,
const SMDS_MeshNode* theSideSecondNode,
const SMDS_MeshNode* theSideThirdNode,
- bool theSideIsFreeBorder)
+ const bool theSideIsFreeBorder,
+ const bool toCreatePolygons,
+ const bool toCreatePolyedrs)
{
MESSAGE("::SewFreeBorder()");
Sew_Error aResult = SEW_OK;
LinkID_Gen aLinkID_Gen( GetMeshDS() );
set<long> foundSideLinkIDs, checkedLinkIDs;
SMDS_VolumeTool volume;
- const SMDS_MeshNode* faceNodes[ 4 ];
+ //const SMDS_MeshNode* faceNodes[ 4 ];
const SMDS_MeshNode* sideNode;
const SMDS_MeshElement* sideElem;
const SMDS_MeshElement* elem = invElemIt->next();
// prepare data for a loop on links, of a face or a volume
int iPrevNode, iNode = 0, nbNodes = elem->NbNodes();
+ const SMDS_MeshNode* faceNodes[ nbNodes ];
bool isVolume = volume.Set( elem );
const SMDS_MeshNode** nodes = isVolume ? volume.GetNodes() : faceNodes;
if ( isVolume ) // --volume
}
while ( sideNode != theSideSecondNode );
- if ( hasVolumes && sideNodes.size () != bordNodes.size() ) {
+ if ( hasVolumes && sideNodes.size () != bordNodes.size() && !toCreatePolyedrs) {
MESSAGE("VOLUME SPLITTING IS FORBIDDEN");
return SEW_VOLUMES_TO_SPLIT; // volume splitting is forbidden
}
list<const SMDS_MeshNode*> & nodeList = (*insertMapIt).second;
const SMDS_MeshNode* n12 = nodeList.front(); nodeList.pop_front();
const SMDS_MeshNode* n22 = nodeList.front(); nodeList.pop_front();
- InsertNodesIntoLink( elem, n12, n22, nodeList );
+ InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePolygons );
// 2. perform insertion into the link of adjacent faces
while (true) {
const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem );
if ( adjElem )
- InsertNodesIntoLink( adjElem, n12, n22, nodeList );
+ InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons );
else
break;
}
+ if (toCreatePolyedrs) {
+ // perform insertion into the links of adjacent volumes
+ UpdateVolumes(n12, n22, nodeList);
+ }
// 3. find an element appeared on n1 and n2 after the insertion
insertMap.erase( elem );
elem = findAdjacentFace( n1, n2, 0 );
const SMDS_MeshNode* n1 = nodeList.front(); nodeList.pop_front();
const SMDS_MeshNode* n2 = nodeList.front(); nodeList.pop_front();
- InsertNodesIntoLink( elem, n1, n2, nodeList );
+ InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePolygons );
if ( !theSideIsFreeBorder ) {
// look for and insert nodes into the faces adjacent to elem
while (true) {
const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem );
if ( adjElem )
- InsertNodesIntoLink( adjElem, n1, n2, nodeList );
+ InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons );
else
break;
}
}
+ if (toCreatePolyedrs) {
+ // perform insertion into the links of adjacent volumes
+ UpdateVolumes(n1, n2, nodeList);
+ }
}
} // end: insert new nodes
void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace,
const SMDS_MeshNode* theBetweenNode1,
const SMDS_MeshNode* theBetweenNode2,
- list<const SMDS_MeshNode*>& theNodesToInsert)
+ list<const SMDS_MeshNode*>& theNodesToInsert,
+ const bool toCreatePoly)
{
if ( theFace->GetType() != SMDSAbs_Face ) return;
// find indices of 2 link nodes and of the rest nodes
int iNode = 0, il1, il2, i3, i4;
il1 = il2 = i3 = i4 = -1;
- const SMDS_MeshNode* nodes[ 8 ];
+ const SMDS_MeshNode* nodes[ theFace->NbNodes() ];
SMDS_ElemIteratorPtr nodeIt = theFace->nodesIterator();
while ( nodeIt->more() ) {
const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
// arrange link nodes to go one after another regarding the face orientation
bool reverse = ( Abs( il2 - il1 ) == 1 ? il2 < il1 : il1 < il2 );
+ list<const SMDS_MeshNode *> aNodesToInsert = theNodesToInsert;
if ( reverse ) {
iNode = il1;
il1 = il2;
il2 = iNode;
- theNodesToInsert.reverse();
+ aNodesToInsert.reverse();
}
// check that not link nodes of a quadrangles are in good order
int nbFaceNodes = theFace->NbNodes();
i4 = iNode;
}
- // put theNodesToInsert between theBetweenNode1 and theBetweenNode2
- int nbLinkNodes = 2 + theNodesToInsert.size();
+ if (toCreatePoly || theFace->IsPoly()) {
+
+ iNode = 0;
+ vector<const SMDS_MeshNode *> poly_nodes (nbFaceNodes + aNodesToInsert.size());
+
+ // add nodes of face up to first node of link
+ bool isFLN = false;
+ nodeIt = theFace->nodesIterator();
+ while ( nodeIt->more() && !isFLN ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ poly_nodes[iNode++] = n;
+ if (n == nodes[il1]) {
+ isFLN = true;
+ }
+ }
+
+ // add nodes to insert
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for (; nIt != aNodesToInsert.end(); nIt++) {
+ poly_nodes[iNode++] = *nIt;
+ }
+
+ // add nodes of face starting from last node of link
+ while ( nodeIt->more() ) {
+ const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
+ poly_nodes[iNode++] = n;
+ }
+
+ // edit or replace the face
+ SMESHDS_Mesh *aMesh = GetMeshDS();
+
+ if (theFace->IsPoly()) {
+ aMesh->ChangePolygonNodes(theFace, poly_nodes);
+
+ } else {
+ int aShapeId = FindShape( theFace );
+
+ SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
+ if ( aShapeId && newElem )
+ aMesh->SetMeshElementOnShape( newElem, aShapeId );
+
+ aMesh->RemoveElement(theFace);
+ }
+ return;
+ }
+
+ // put aNodesToInsert between theBetweenNode1 and theBetweenNode2
+ int nbLinkNodes = 2 + aNodesToInsert.size();
const SMDS_MeshNode* linkNodes[ nbLinkNodes ];
linkNodes[ 0 ] = nodes[ il1 ];
linkNodes[ nbLinkNodes - 1 ] = nodes[ il2 ];
- list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
- for ( iNode = 1; nIt != theNodesToInsert.end(); nIt++ ) {
+ list<const SMDS_MeshNode*>::iterator nIt = aNodesToInsert.begin();
+ for ( iNode = 1; nIt != aNodesToInsert.end(); nIt++ ) {
linkNodes[ iNode++ ] = *nIt;
}
// decide how to split a quadrangle: compare possible variants
}
//=======================================================================
+//function : UpdateVolumes
+//purpose :
+//=======================================================================
+void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode1,
+ const SMDS_MeshNode* theBetweenNode2,
+ list<const SMDS_MeshNode*>& theNodesToInsert)
+{
+ SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator();
+ while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1
+ const SMDS_MeshElement* elem = invElemIt->next();
+ if (elem->GetType() != SMDSAbs_Volume)
+ continue;
+
+ // check, if current volume has link theBetweenNode1 - theBetweenNode2
+ SMDS_VolumeTool aVolume (elem);
+ if (!aVolume.IsLinked(theBetweenNode1, theBetweenNode2))
+ continue;
+
+ // insert new nodes in all faces of the volume, sharing link theBetweenNode1 - theBetweenNode2
+ int iface, nbFaces = aVolume.NbFaces();
+ vector<const SMDS_MeshNode *> poly_nodes;
+ vector<int> quantities (nbFaces);
+
+ for (iface = 0; iface < nbFaces; iface++) {
+ int nbFaceNodes = aVolume.NbFaceNodes(iface), nbInserted = 0;
+ // faceNodes will contain (nbFaceNodes + 1) nodes, last = first
+ const SMDS_MeshNode** faceNodes = aVolume.GetFaceNodes(iface);
+
+ for (int inode = 0; inode < nbFaceNodes; inode++) {
+ poly_nodes.push_back(faceNodes[inode]);
+
+ if (nbInserted == 0) {
+ if (faceNodes[inode] == theBetweenNode1) {
+ if (faceNodes[inode + 1] == theBetweenNode2) {
+ nbInserted = theNodesToInsert.size();
+
+ // add nodes to insert
+ list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
+ for (; nIt != theNodesToInsert.end(); nIt++) {
+ poly_nodes.push_back(*nIt);
+ }
+ }
+ } else if (faceNodes[inode] == theBetweenNode2) {
+ if (faceNodes[inode + 1] == theBetweenNode1) {
+ nbInserted = theNodesToInsert.size();
+
+ // add nodes to insert in reversed order
+ list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.end();
+ nIt--;
+ for (; nIt != theNodesToInsert.begin(); nIt--) {
+ poly_nodes.push_back(*nIt);
+ }
+ poly_nodes.push_back(*nIt);
+ }
+ } else {
+ }
+ }
+ }
+ quantities[iface] = nbFaceNodes + nbInserted;
+ }
+
+ // Replace or update the volume
+ SMESHDS_Mesh *aMesh = GetMeshDS();
+
+ if (elem->IsPoly()) {
+ aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
+
+ } else {
+ int aShapeId = FindShape( elem );
+
+ SMDS_MeshElement* newElem =
+ aMesh->AddPolyhedralVolume(poly_nodes, quantities);
+ if (aShapeId && newElem)
+ aMesh->SetMeshElementOnShape(newElem, aShapeId);
+
+ aMesh->RemoveElement(elem);
+ }
+ }
+}
+
+//=======================================================================
//function : SewSideElements
//purpose :
//=======================================================================
bool isNewFace = setOfFaceNodeSet.insert( faceNodeSet ).second;
if ( isNewFace ) {
// no such a face is given but it still can exist, check it
- if ( nbNodes == 3 )
+ if ( nbNodes == 3 ) {
aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2] );
- else
+ } else if ( nbNodes == 4 ) {
aFreeFace = aMesh->FindFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+ } else {
+ vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
+ for (int inode = 0; inode < nbNodes; inode++) {
+ poly_nodes[inode] = fNodes[inode];
+ }
+ aFreeFace = aMesh->FindFace(poly_nodes);
+ }
}
if ( !aFreeFace ) {
// create a temporary face
- if ( nbNodes == 3 )
+ if ( nbNodes == 3 ) {
aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2] );
- else
+ } else if ( nbNodes == 4 ) {
aFreeFace = aTmpFacesMesh.AddFace( fNodes[0],fNodes[1],fNodes[2],fNodes[3] );
+ } else {
+ vector<const SMDS_MeshNode *> poly_nodes (nbNodes);
+ for (int inode = 0; inode < nbNodes; inode++) {
+ poly_nodes[inode] = fNodes[inode];
+ }
+ aFreeFace = aTmpFacesMesh.AddPolygonalFace(poly_nodes);
+ }
}
if ( aFreeFace )
freeFaceList.push_back( aFreeFace );
std::set<const SMDS_MeshNode*> & theFixedNodes,
const SmoothMethod theSmoothMethod,
const int theNbIterations,
- double theTgtAspectRatio = 1.0);
+ double theTgtAspectRatio = 1.0,
+ const bool the2D = true);
// Smooth theElements using theSmoothMethod during theNbIterations
// or until a worst element has aspect ratio <= theTgtAspectRatio.
// Aspect Ratio varies in range [1.0, inf].
// If theElements is empty, the whole mesh is smoothed.
// theFixedNodes contains additionally fixed nodes. Nodes built
// on edges and boundary nodes are always fixed.
+ // If the2D, smoothing is performed using UV parameters of nodes
+ // on geometrical faces
void RotationSweep (std::set<const SMDS_MeshElement*> & theElements,
// Return list of group of nodes close to each other within theTolerance.
// Search among theNodes or in the whole mesh if theNodes is empty.
+ int SimplifyFace (const vector<const SMDS_MeshNode *> faceNodes,
+ vector<const SMDS_MeshNode *>& poly_nodes,
+ vector<int>& quantities) const;
+ // Split face, defined by <faceNodes>, into several faces by repeating nodes.
+ // Is used by MergeNodes()
+
void MergeNodes (TListOfListOfNodes & theNodeGroups);
// In each group, the cdr of nodes are substituted by the first one
// in all elements.
const SMDS_MeshNode* theSide2FirstNode,
const SMDS_MeshNode* theSide2SecondNode,
const SMDS_MeshNode* theSide2ThirdNode = 0,
- bool theSide2IsFreeBorder = true);
+ const bool theSide2IsFreeBorder = true,
+ const bool toCreatePolygons = false,
+ const bool toCreatePolyedrs = false);
// Sew the free border to the side2 by replacing nodes in
// elements on the free border with nodes of the elements
// of the side 2. If nb of links in the free border and
void InsertNodesIntoLink(const SMDS_MeshElement* theFace,
const SMDS_MeshNode* theBetweenNode1,
const SMDS_MeshNode* theBetweenNode2,
- std::list<const SMDS_MeshNode*>& theNodesToInsert);
- // insert theNodesToInsert into theFace between theBetweenNode1
- // and theBetweenNode2 and split theElement.
-
- static int SortQuadNodes (const SMDS_Mesh * theMesh,
- int theNodeIds[] );
- // Set 4 nodes of a quadrangle face in a good order.
- // Swap 1<->2 or 2<->3 nodes and correspondingly return
- // 1 or 2 else 0.
-
- static bool SortHexaNodes (const SMDS_Mesh * theMesh,
- int theNodeIds[] );
- // Set 8 nodes of a hexahedron in a good order.
- // Return success status
+ std::list<const SMDS_MeshNode*>& theNodesToInsert,
+ const bool toCreatePoly = false);
+ // insert theNodesToInsert into theFace between theBetweenNode1 and theBetweenNode2.
+ // If toCreatePoly is true, replace theFace by polygon, else split theFace.
+
+ void UpdateVolumes (const SMDS_MeshNode* theBetweenNode1,
+ const SMDS_MeshNode* theBetweenNode2,
+ std::list<const SMDS_MeshNode*>& theNodesToInsert);
+ // insert theNodesToInsert into all volumes, containing link
+ // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2.
+
+// static int SortQuadNodes (const SMDS_Mesh * theMesh,
+// int theNodeIds[] );
+// // Set 4 nodes of a quadrangle face in a good order.
+// // Swap 1<->2 or 2<->3 nodes and correspondingly return
+// // 1 or 2 else 0.
+//
+// static bool SortHexaNodes (const SMDS_Mesh * theMesh,
+// int theNodeIds[] );
+// // Set 8 nodes of a hexahedron in a good order.
+// // Return success status
static void AddToSameGroups (const SMDS_MeshElement* elemToAdd,
const SMDS_MeshElement* elemInGroups,
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshFace.hxx"
#include "SMDS_MeshNode.hxx"
+#include "SMDS_VolumeTool.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESHDS_SubMesh.hxx"
while ( readLine( fields, lineBeg, clearFields ))
{
- myElemPointIDs.push_back( list< int >() );
- list< int >& elemPoints = myElemPointIDs.back();
+ myElemPointIDs.push_back( TElemDef() );
+ TElemDef& elemPoints = myElemPointIDs.back();
for ( fIt = fields.begin(); fIt != fields.end(); fIt++ )
{
int pointIndex = getInt( *fIt );
}
// elements
theFile << "!!! Indices of points of " << myElemPointIDs.size() << " elements:" << endl;
- list<list< int > >::const_iterator epIt = myElemPointIDs.begin();
+ list<TElemDef >::const_iterator epIt = myElemPointIDs.begin();
for ( ; epIt != myElemPointIDs.end(); epIt++ )
{
- const list< int > & elemPoints = *epIt;
- list< int >::const_iterator iIt = elemPoints.begin();
+ const TElemDef & elemPoints = *epIt;
+ TElemDef::const_iterator iIt = elemPoints.begin();
for ( ; iIt != elemPoints.end(); iIt++ )
theFile << " " << *iIt;
theFile << endl;
SMDS_FaceIteratorPtr fIt = aMeshDS->facesIterator();
while ( fIt->more() )
{
- myElemPointIDs.push_back( list< int >() );
- list< int >& elemPoints = myElemPointIDs.back();
+ myElemPointIDs.push_back( TElemDef() );
+ TElemDef& elemPoints = myElemPointIDs.back();
SMDS_ElemIteratorPtr nIt = fIt->next()->nodesIterator();
while ( nIt->more() )
{
SMDS_ElemIteratorPtr elemIt = fSubMesh->GetElements();
while ( elemIt->more() ) {
SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator();
- myElemPointIDs.push_back( list< int >() );
- list< int >& elemPoints = myElemPointIDs.back();
+ myElemPointIDs.push_back( TElemDef() );
+ TElemDef& elemPoints = myElemPointIDs.back();
while ( nIt->more() )
elemPoints.push_back( nodePointIDMap[ nIt->next() ]);
}
const int theNodeIndexOnKeyPoint1,
const bool theReverse)
{
- MESSAGE(" ::Apply(MeshFace) " );
+// MESSAGE(" ::Apply(MeshFace) " );
if ( !IsLoaded() ) {
MESSAGE( "Pattern not loaded" );
}
//=======================================================================
-//function : mergePoints
-//purpose : Look for coincident points between myXYZs indexed with
-// list<int> of each element of xyzIndGroups. Coincident indices
-// are merged in myElemXYZIDs.
-//=======================================================================
-
-void SMESH_Pattern::mergePoints (map<TNodeSet, list<list<int> > >& indGroups,
- map< int, list< list< int >* > > & reverseConnectivity)
-{
- map< TNodeSet, list< list< int > > >::iterator indListIt;
- for ( indListIt = indGroups.begin(); indListIt != indGroups.end(); indListIt++ )
- {
- list<list< int > > groups = indListIt->second;
- if ( groups.size() < 2 )
- continue;
-
-// const TNodeSet & nodes = indListIt->first;
-// TNodeSet::const_iterator n = nodes.begin();
-// for ( ; n != nodes.end(); n++ )
-// cout << *n ;
-
- // find tolerance
- Bnd_Box box;
- list< int >& indices = groups.front();
- list< int >::iterator ind, ind1, ind2;
- for ( ind = indices.begin(); ind != indices.end(); ind++ )
- box.Add( gp_Pnt( myXYZ[ *ind ]));
- double x, y, z, X, Y, Z;
- box.Get( x, y, z, X, Y, Z );
- gp_Pnt p( x, y, z ), P( X, Y, Z );
- double tol2 = 1.e-4 * p.SquareDistance( P );
-
- // compare points, replace indices
-
- list< list< int > >::iterator grpIt1, grpIt2;
- for ( grpIt1 = groups.begin(); grpIt1 != groups.end(); grpIt1++ )
- {
- list< int >& indices1 = *grpIt1;
- grpIt2 = grpIt1;
- for ( grpIt2++; grpIt2 != groups.end(); grpIt2++ )
- {
- list< int >& indices2 = *grpIt2;
- for ( ind1 = indices1.begin(); ind1 != indices1.end(); ind1++ )
- {
- gp_XYZ& p1 = myXYZ[ *ind1 ];
- ind2 = indices2.begin();
- while ( ind2 != indices2.end() )
- {
- gp_XYZ& p2 = myXYZ[ *ind2 ];
- //MESSAGE("COMP: " << *ind1 << " " << *ind2 << " X: " << p2.X() << " tol2: " << tol2);
- if ( ( p1 - p2 ).SquareModulus() <= tol2 )
- {
- ASSERT( reverseConnectivity.find( *ind2 ) != reverseConnectivity.end() );
- list< list< int >* > & elemXYZIDsList = reverseConnectivity[ *ind2 ];
- list< list< int >* >::iterator elemXYZIDs = elemXYZIDsList.begin();
- for ( ; elemXYZIDs != elemXYZIDsList.end(); elemXYZIDs++ )
- {
- ind = find( (*elemXYZIDs)->begin(), (*elemXYZIDs)->end(), *ind2 );
- //MESSAGE( " Replace " << *ind << " with " << *ind1 );
- myXYZ[ *ind ] = undefinedXYZ();
- *ind = *ind1;
- }
- ind2 = indices2.erase( ind2 );
- }
- else
- ind2++;
- }
- }
- }
- }
- }
-}
-
-//=======================================================================
//function : Apply
//purpose : Compute nodes coordinates applying
// the loaded pattern to <theFaces>. The first key-point
// will be mapped into <theNodeIndexOnKeyPoint1>-th node
//=======================================================================
-bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
- const int theNodeIndexOnKeyPoint1,
- const bool theReverse)
+bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*>& theFaces,
+ const int theNodeIndexOnKeyPoint1,
+ const bool theReverse)
{
MESSAGE(" ::Apply(set<MeshFace>) " );
return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
}
+ myShape.Nullify();
myXYZ.clear();
myElemXYZIDs.clear();
myXYZIdToNodeMap.clear();
myElements.clear();
+ myIdsOnBoundary.clear();
+ myReverseConnectivity.clear();
myXYZ.resize( myPoints.size() * theFaces.size(), undefinedXYZ() );
myElements.reserve( theFaces.size() );
for ( int i = 0; i < myPoints.size(); i++ )
pointIndex.insert( make_pair( & myPoints[ i ], i ));
- // to merge nodes on edges of the elements being refined
- typedef set<const SMDS_MeshNode*> TLink;
- map< TLink, list< list< int > > > linkPointIndListMap;
- map< int, list< list< int >* > > reverseConnectivity;
-
int ind1 = 0; // lowest point index for a face
// apply to each face in theFaces set
myElements.push_back( *face );
// store computed points belonging to elements
- list< list< int > >::iterator ll = myElemPointIDs.begin();
+ list< TElemDef >::iterator ll = myElemPointIDs.begin();
for ( ; ll != myElemPointIDs.end(); ++ll )
{
- myElemXYZIDs.push_back();
- list< int >& xyzIds = myElemXYZIDs.back();
- list< int >& pIds = *ll;
- for ( list<int>::iterator id = pIds.begin(); id != pIds.end(); id++ ) {
+ myElemXYZIDs.push_back(TElemDef());
+ TElemDef& xyzIds = myElemXYZIDs.back();
+ TElemDef& pIds = *ll;
+ for ( TElemDef::iterator id = pIds.begin(); id != pIds.end(); id++ ) {
int pIndex = *id + ind1;
xyzIds.push_back( pIndex );
myXYZ[ pIndex ] = myPoints[ *id ].myXYZ.XYZ();
- reverseConnectivity[ pIndex ].push_back( & xyzIds );
+ myReverseConnectivity[ pIndex ].push_back( & xyzIds );
}
}
- // put points on links to linkPointIndListMap
+ // put points on links to myIdsOnBoundary,
+ // they will be used to sew new elements on adjacent refined elements
int nbNodes = (*face)->NbNodes(), eID = nbNodes + 1;
for ( int i = 0; i < nbNodes; i++ )
{
+ list< TPoint* > & linkPoints = getShapePoints( eID++ );
const SMDS_MeshNode* n1 = myOrderedNodes[ i ];
const SMDS_MeshNode* n2 = myOrderedNodes[ i + 1 == nbNodes ? 0 : i + 1 ];
- // make a link of node pointers
- TLink link;
- link.insert( n1 );
- link.insert( n2 );
- // add the link to the map
- list< list< int > >& groups = linkPointIndListMap[ link ];
- groups.push_back();
- list< int >& indList = groups.back();
- list< TPoint* > & linkPoints = getShapePoints( eID++ );
+ // make a link and a node set
+ TNodeSet linkSet, node1Set;
+ linkSet.insert( n1 );
+ linkSet.insert( n2 );
+ node1Set.insert( n1 );
list< TPoint* >::iterator p = linkPoints.begin();
- // map the first link point to n1
- myXYZIdToNodeMap[ pointIndex[ *p ] + ind1 ] = n1;
+ {
+ // map the first link point to n1
+ int nId = pointIndex[ *p ] + ind1;
+ myXYZIdToNodeMap[ nId ] = n1;
+ list< list< int > >& groups = myIdsOnBoundary[ node1Set ];
+ groups.push_back(list< int > ());
+ groups.back().push_back( nId );
+ }
+ // add the linkSet to the map
+ list< list< int > >& groups = myIdsOnBoundary[ linkSet ];
+ groups.push_back(list< int > ());
+ list< int >& indList = groups.back();
// add points to the map excluding the end points
for ( p++; *p != linkPoints.back(); p++ )
indList.push_back( pointIndex[ *p ] + ind1 );
ind1 += myPoints.size();
}
- mergePoints( linkPointIndListMap, reverseConnectivity );
-
return !myElemXYZIDs.empty();
}
// node.
//=======================================================================
-bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> theVolumes,
- const int theNode000Index,
- const int theNode001Index)
+bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> & theVolumes,
+ const int theNode000Index,
+ const int theNode001Index)
{
MESSAGE(" ::Apply(set<MeshVolumes>) " );
return setErrorCode( ERR_APPL_BAD_NB_VERTICES );
}
+ myShape.Nullify();
myXYZ.clear();
myElemXYZIDs.clear();
myXYZIdToNodeMap.clear();
myElements.clear();
+ myIdsOnBoundary.clear();
+ myReverseConnectivity.clear();
myXYZ.resize( myPoints.size() * theVolumes.size(), undefinedXYZ() );
myElements.reserve( theVolumes.size() );
for ( int i = 0; i < myPoints.size(); i++ )
pointIndex.insert( make_pair( & myPoints[ i ], i ));
- // to merge nodes on edges and faces of the elements being refined
- map< TNodeSet, list< list< int > > > subPointIndListMap;
- map< int, list< list< int >* > > reverseConnectivity;
-
int ind1 = 0; // lowest point index for an element
// apply to each element in theVolumes set
myElements.push_back( *vol );
// store computed points belonging to elements
- list< list< int > >::iterator ll = myElemPointIDs.begin();
+ list< TElemDef >::iterator ll = myElemPointIDs.begin();
for ( ; ll != myElemPointIDs.end(); ++ll )
{
- myElemXYZIDs.push_back();
- list< int >& xyzIds = myElemXYZIDs.back();
- list< int >& pIds = *ll;
- for ( list<int>::iterator id = pIds.begin(); id != pIds.end(); id++ ) {
+ myElemXYZIDs.push_back(TElemDef());
+ TElemDef& xyzIds = myElemXYZIDs.back();
+ TElemDef& pIds = *ll;
+ for ( TElemDef::iterator id = pIds.begin(); id != pIds.end(); id++ ) {
int pIndex = *id + ind1;
xyzIds.push_back( pIndex );
myXYZ[ pIndex ] = myPoints[ *id ].myXYZ.XYZ();
- reverseConnectivity[ pIndex ].push_back( & xyzIds );
+ myReverseConnectivity[ pIndex ].push_back( & xyzIds );
}
}
- // put points on edges and faces to subPointIndListMap
+ // put points on edges and faces to myIdsOnBoundary,
+ // they will be used to sew new elements on adjacent refined elements
for ( int Id = SMESH_Block::ID_V000; Id <= SMESH_Block::ID_F1yz; Id++ )
{
// make a set of sub-points
TNodeSet subNodes;
vector< int > subIDs;
if ( SMESH_Block::IsVertexID( Id )) {
- // use nodes of refined volumes for merge
+ subNodes.insert( myOrderedNodes[ Id - 1 ]);
}
else if ( SMESH_Block::IsEdgeID( Id )) {
SMESH_Block::GetEdgeVertexIDs( Id, subIDs );
subNodes.insert( myOrderedNodes[ subIDs.front() - 1 ]);
subNodes.insert( myOrderedNodes[ subIDs.back() - 1 ]);
}
- list< list< int > >& groups = subPointIndListMap[ subNodes ];
- groups.push_back();
- list< int >& indList = groups.back();
// add points
list< TPoint* > & points = getShapePoints( Id );
list< TPoint* >::iterator p = points.begin();
- if ( subNodes.empty() ) // vertex case
- myXYZIdToNodeMap[ pointIndex[ *p ] + ind1 ] = myOrderedNodes[ Id - 1 ];
- else
- for ( ; p != points.end(); p++ )
- indList.push_back( pointIndex[ *p ] + ind1 );
+ list< list< int > >& groups = myIdsOnBoundary[ subNodes ];
+ groups.push_back(list< int > ());
+ list< int >& indList = groups.back();
+ for ( ; p != points.end(); p++ )
+ indList.push_back( pointIndex[ *p ] + ind1 );
+ if ( subNodes.size() == 1 ) // vertex case
+ myXYZIdToNodeMap[ indList.back() ] = myOrderedNodes[ Id - 1 ];
}
ind1 += myPoints.size();
}
- mergePoints( subPointIndListMap, reverseConnectivity );
-
return !myElemXYZIDs.empty();
}
SMDS_ElemIteratorPtr elemIt = aSubMesh->GetElements();
while ( elemIt->more() ) {
SMDS_ElemIteratorPtr nIt = elemIt->next()->nodesIterator();
- myElemPointIDs.push_back( list< int >() );
- list< int >& elemPoints = myElemPointIDs.back();
+ myElemPointIDs.push_back( TElemDef() );
+ TElemDef& elemPoints = myElemPointIDs.back();
while ( nIt->more() )
elemPoints.push_back( nodePointIDMap[ nIt->next() ]);
}
const int theNode000Index,
const int theNode001Index)
{
- MESSAGE(" ::Apply(MeshVolume) " );
+ //MESSAGE(" ::Apply(MeshVolume) " );
if (!findBoundaryPoints()) // bind ID to points
return false;
}
//=======================================================================
+//function : mergePoints
+//purpose : Merge XYZ on edges and/or faces.
+//=======================================================================
+
+void SMESH_Pattern::mergePoints (const bool uniteGroups)
+{
+ map< TNodeSet, list< list< int > > >::iterator idListIt = myIdsOnBoundary.begin();
+ for ( ; idListIt != myIdsOnBoundary.end(); idListIt++ )
+ {
+ list<list< int > >& groups = idListIt->second;
+ if ( groups.size() < 2 )
+ continue;
+
+ // find tolerance
+ const TNodeSet& nodes = idListIt->first;
+ double tol2 = 1.e-10;
+ if ( nodes.size() > 1 ) {
+ Bnd_Box box;
+ TNodeSet::const_iterator n = nodes.begin();
+ for ( ; n != nodes.end(); ++n )
+ box.Add( gp_Pnt( (*n)->X(), (*n)->Y(), (*n)->Z() ));
+ double x, y, z, X, Y, Z;
+ box.Get( x, y, z, X, Y, Z );
+ gp_Pnt p( x, y, z ), P( X, Y, Z );
+ tol2 = 1.e-4 * p.SquareDistance( P );
+ }
+
+ // to unite groups on link
+ bool unite = ( uniteGroups && nodes.size() == 2 );
+ map< double, int > distIndMap;
+ const SMDS_MeshNode* node = *nodes.begin();
+ gp_Pnt P( node->X(), node->Y(), node->Z() );
+
+ // compare points, replace indices
+
+ list< int >::iterator ind1, ind2;
+ list< list< int > >::iterator grpIt1, grpIt2;
+ for ( grpIt1 = groups.begin(); grpIt1 != groups.end(); grpIt1++ )
+ {
+ list< int >& indices1 = *grpIt1;
+ grpIt2 = grpIt1;
+ for ( grpIt2++; grpIt2 != groups.end(); grpIt2++ )
+ {
+ list< int >& indices2 = *grpIt2;
+ for ( ind1 = indices1.begin(); ind1 != indices1.end(); ind1++ )
+ {
+ gp_XYZ& p1 = myXYZ[ *ind1 ];
+ ind2 = indices2.begin();
+ while ( ind2 != indices2.end() )
+ {
+ gp_XYZ& p2 = myXYZ[ *ind2 ];
+ //MESSAGE("COMP: " << *ind1 << " " << *ind2 << " X: " << p2.X() << " tol2: " << tol2);
+ if ( ( p1 - p2 ).SquareModulus() <= tol2 )
+ {
+ ASSERT( myReverseConnectivity.find( *ind2 ) != myReverseConnectivity.end() );
+ list< TElemDef* > & elemXYZIDsList = myReverseConnectivity[ *ind2 ];
+ list< TElemDef* >::iterator elemXYZIDs = elemXYZIDsList.begin();
+ for ( ; elemXYZIDs != elemXYZIDsList.end(); elemXYZIDs++ )
+ {
+ //MESSAGE( " Replace " << *ind2 << " with " << *ind1 );
+ myXYZ[ *ind2 ] = undefinedXYZ();
+ replace( (*elemXYZIDs)->begin(), (*elemXYZIDs)->end(), *ind2, *ind1 );
+ }
+ ind2 = indices2.erase( ind2 );
+ }
+ else
+ ind2++;
+ }
+ }
+ }
+ if ( unite ) { // sort indices using distIndMap
+ for ( ind1 = indices1.begin(); ind1 != indices1.end(); ind1++ )
+ {
+ ASSERT( isDefined( myXYZ[ *ind1 ] ));
+ double dist = P.SquareDistance( myXYZ[ *ind1 ]);
+ distIndMap.insert( make_pair( dist, *ind1 ));
+ }
+ }
+ }
+ if ( unite ) { // put all sorted indices into the first group
+ list< int >& g = groups.front();
+ g.clear();
+ map< double, int >::iterator dist_ind = distIndMap.begin();
+ for ( ; dist_ind != distIndMap.end(); dist_ind++ )
+ g.push_back( dist_ind->second );
+ }
+ } // loop on myIdsOnBoundary
+}
+
+//=======================================================================
+//function : makePolyElements
+//purpose : prepare intermediate data to create Polygons and Polyhedrons
+//=======================================================================
+
+void SMESH_Pattern::
+ makePolyElements(const vector< const SMDS_MeshNode* >& theNodes,
+ const bool toCreatePolygons,
+ const bool toCreatePolyedrs)
+{
+ myPolyElemXYZIDs.clear();
+ myPolyElems.clear();
+ myPolyElems.reserve( myIdsOnBoundary.size() );
+
+ // make a set of refined elements
+ set< const SMDS_MeshElement* > avoidSet, elemSet;
+ avoidSet.insert( myElements.begin(), myElements.end() );
+
+ map< TNodeSet, list< list< int > > >::iterator indListIt, nn_IdList;
+
+ if ( toCreatePolygons )
+ {
+ int lastFreeId = myXYZ.size();
+
+ // loop on links of refined elements
+ indListIt = myIdsOnBoundary.begin();
+ for ( ; indListIt != myIdsOnBoundary.end(); indListIt++ )
+ {
+ const TNodeSet & linkNodes = indListIt->first;
+ if ( linkNodes.size() != 2 )
+ continue; // skip face
+ const SMDS_MeshNode* n1 = * linkNodes.begin();
+ const SMDS_MeshNode* n2 = * linkNodes.rbegin();
+
+ list<list< int > >& idGroups = indListIt->second; // ids of nodes to build
+ if ( idGroups.empty() || idGroups.front().empty() )
+ continue;
+
+ // find not refined face having n1-n2 link
+
+ while (true)
+ {
+ const SMDS_MeshElement* face =
+ SMESH_MeshEditor::FindFaceInSet( n1, n2, elemSet, avoidSet );
+ if ( face )
+ {
+ avoidSet.insert ( face );
+ myPolyElems.push_back( face );
+
+ // some links of <face> are split;
+ // make list of xyz for <face>
+ myPolyElemXYZIDs.push_back(TElemDef());
+ TElemDef & faceNodeIds = myPolyElemXYZIDs.back();
+ // loop on links of a <face>
+ SMDS_ElemIteratorPtr nIt = face->nodesIterator();
+ int i = 0, nbNodes = face->NbNodes();
+ vector<const SMDS_MeshNode*> nodes( nbNodes + 1 );
+ while ( nIt->more() )
+ nodes[ i++ ] = static_cast<const SMDS_MeshNode*>( nIt->next() );
+ nodes[ i ] = nodes[ 0 ];
+ for ( i = 0; i < nbNodes; ++i )
+ {
+ // look for point mapped on a link
+ TNodeSet faceLinkNodes;
+ faceLinkNodes.insert( nodes[ i ] );
+ faceLinkNodes.insert( nodes[ i + 1 ] );
+ if ( faceLinkNodes == linkNodes )
+ nn_IdList = indListIt;
+ else
+ nn_IdList = myIdsOnBoundary.find( faceLinkNodes );
+ // add face point ids
+ faceNodeIds.push_back( ++lastFreeId );
+ myXYZIdToNodeMap.insert( make_pair( lastFreeId, nodes[ i ]));
+ if ( nn_IdList != myIdsOnBoundary.end() )
+ {
+ // there are points mapped on a link
+ list< int >& mappedIds = nn_IdList->second.front();
+ if ( isReversed( nodes[ i ], mappedIds ))
+ faceNodeIds.insert (faceNodeIds.end(),mappedIds.rbegin(), mappedIds.rend() );
+ else
+ faceNodeIds.insert (faceNodeIds.end(),mappedIds.begin(), mappedIds.end() );
+ }
+ } // loop on links of a <face>
+ } // if ( face )
+ else
+ break;
+ } // while (true)
+
+ if ( myIs2D && idGroups.size() > 1 ) {
+
+ // sew new elements on 2 refined elements sharing n1-n2 link
+
+ list< int >& idsOnLink = idGroups.front();
+ // temporarily add ids of link nodes to idsOnLink
+ bool rev = isReversed( n1, idsOnLink );
+ for ( int i = 0; i < 2; ++i )
+ {
+ TNodeSet nodeSet;
+ nodeSet.insert( i ? n2 : n1 );
+ ASSERT( myIdsOnBoundary.find( nodeSet ) != myIdsOnBoundary.end() );
+ list<list< int > >& groups = myIdsOnBoundary[ nodeSet ];
+ int nodeId = groups.front().front();
+ &nb