Salome HOME
SMH: Preparation version 3.0.0 - merge (HEAD+POLYWORK) T_3_0_0_a1
authorsmh <smh@opencascade.com>
Tue, 7 Jun 2005 13:22:20 +0000 (13:22 +0000)
committersmh <smh@opencascade.com>
Tue, 7 Jun 2005 13:22:20 +0000 (13:22 +0000)
192 files changed:
INSTALL
Makefile.in
adm_local/unix/make_commence.in
adm_local/unix/make_conclude.in
bin/VERSION
configure.in.base
idl/SMESH_Filter.idl
idl/SMESH_Group.idl
idl/SMESH_Mesh.idl
idl/SMESH_Pattern.idl
resources/SMESHCatalog.xml
resources/SMESH_en.xml
resources/mesh_polygon.png [new file with mode: 0644]
resources/mesh_polyhedron.png [new file with mode: 0644]
src/Controls/SMESH_Controls.cxx
src/Controls/SMESH_ControlsDef.hxx
src/DriverMED/DriverMED_R_SMESHDS_Mesh.cxx
src/DriverMED/DriverMED_W_SMESHDS_Mesh.cxx
src/DriverSTL/DriverSTL_R_SMDS_Mesh.cxx
src/OBJECT/Makefile.in
src/OBJECT/SMESH_Actor.cxx
src/OBJECT/SMESH_Actor.h
src/OBJECT/SMESH_ActorDef.h
src/OBJECT/SMESH_ActorUtils.cxx
src/OBJECT/SMESH_DeviceActor.cxx
src/OBJECT/SMESH_DeviceActor.h
src/OBJECT/SMESH_Object.cxx
src/OBJECT/SMESH_ObjectDef.h
src/SMDS/Makefile.in
src/SMDS/SMDS_Mesh.cxx
src/SMDS/SMDS_Mesh.hxx
src/SMDS/SMDS_MeshElement.hxx
src/SMDS/SMDS_MeshGroup.cxx
src/SMDS/SMDS_MeshIDFactory.cxx
src/SMDS/SMDS_MeshIDFactory.hxx
src/SMDS/SMDS_PolygonalFaceOfNodes.cxx [new file with mode: 0644]
src/SMDS/SMDS_PolygonalFaceOfNodes.hxx [new file with mode: 0644]
src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx [new file with mode: 0644]
src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx [new file with mode: 0644]
src/SMDS/SMDS_VolumeTool.cxx
src/SMDS/SMDS_VolumeTool.hxx
src/SMESH/SMESH_Mesh.cxx
src/SMESH/SMESH_Mesh.hxx
src/SMESH/SMESH_MeshEditor.cxx
src/SMESH/SMESH_MeshEditor.hxx
src/SMESH/SMESH_Pattern.cxx
src/SMESH/SMESH_Pattern.hxx
src/SMESH/SMESH_subMesh.cxx
src/SMESHDS/SMESHDS_Command.cxx
src/SMESHDS/SMESHDS_Command.hxx
src/SMESHDS/SMESHDS_CommandType.hxx
src/SMESHDS/SMESHDS_Mesh.cxx
src/SMESHDS/SMESHDS_Mesh.hxx
src/SMESHDS/SMESHDS_Script.cxx
src/SMESHDS/SMESHDS_Script.hxx
src/SMESHFiltersSelection/Makefile.in
src/SMESHFiltersSelection/SMESH_LogicalFilter.cxx
src/SMESHFiltersSelection/SMESH_LogicalFilter.hxx
src/SMESHFiltersSelection/SMESH_NumberFilter.cxx
src/SMESHFiltersSelection/SMESH_NumberFilter.hxx
src/SMESHFiltersSelection/SMESH_Type.h
src/SMESHFiltersSelection/SMESH_TypeFilter.cxx
src/SMESHFiltersSelection/SMESH_TypeFilter.hxx
src/SMESHGUI/Makefile.in
src/SMESHGUI/SMESHGUI.cxx
src/SMESHGUI/SMESHGUI.h
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx
src/SMESHGUI/SMESHGUI_AddMeshElementDlg.h
src/SMESHGUI/SMESHGUI_AddSubMeshDlg.cxx
src/SMESHGUI/SMESHGUI_AddSubMeshDlg.h
src/SMESHGUI/SMESHGUI_ClippingDlg.cxx
src/SMESHGUI/SMESHGUI_ClippingDlg.h
src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.cxx
src/SMESHGUI/SMESHGUI_CreateHypothesesDlg.h
src/SMESHGUI/SMESHGUI_CreatePatternDlg.cxx
src/SMESHGUI/SMESHGUI_CreatePatternDlg.h
src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_CreatePolyhedralVolumeDlg.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_DeleteGroupDlg.cxx
src/SMESHGUI/SMESHGUI_DeleteGroupDlg.h
src/SMESHGUI/SMESHGUI_EditHypothesesDlg.cxx
src/SMESHGUI/SMESHGUI_EditHypothesesDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionAlongPathDlg.h
src/SMESHGUI/SMESHGUI_ExtrusionDlg.cxx
src/SMESHGUI/SMESHGUI_ExtrusionDlg.h
src/SMESHGUI/SMESHGUI_Filter.cxx
src/SMESHGUI/SMESHGUI_Filter.h
src/SMESHGUI/SMESHGUI_FilterDlg.cxx
src/SMESHGUI/SMESHGUI_FilterDlg.h
src/SMESHGUI/SMESHGUI_FilterLibraryDlg.cxx
src/SMESHGUI/SMESHGUI_FilterUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.cxx
src/SMESHGUI/SMESHGUI_GEOMGenUtils.h
src/SMESHGUI/SMESHGUI_GroupDlg.cxx
src/SMESHGUI/SMESHGUI_GroupDlg.h
src/SMESHGUI/SMESHGUI_GroupOpDlg.cxx
src/SMESHGUI/SMESHGUI_GroupOpDlg.h
src/SMESHGUI/SMESHGUI_GroupUtils.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.cxx
src/SMESHGUI/SMESHGUI_HypothesesUtils.h
src/SMESHGUI/SMESHGUI_InitMeshDlg.cxx
src/SMESHGUI/SMESHGUI_InitMeshDlg.h
src/SMESHGUI/SMESHGUI_MergeNodesDlg.cxx
src/SMESHGUI/SMESHGUI_MergeNodesDlg.h
src/SMESHGUI/SMESHGUI_MeshInfosDlg.cxx
src/SMESHGUI/SMESHGUI_MeshInfosDlg.h
src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx
src/SMESHGUI/SMESHGUI_MeshPatternDlg.h
src/SMESHGUI/SMESHGUI_MoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_MoveNodesDlg.h
src/SMESHGUI/SMESHGUI_MultiEditDlg.cxx
src/SMESHGUI/SMESHGUI_MultiEditDlg.h
src/SMESHGUI/SMESHGUI_NodesDlg.cxx
src/SMESHGUI/SMESHGUI_NodesDlg.h
src/SMESHGUI/SMESHGUI_PatternUtils.cxx
src/SMESHGUI/SMESHGUI_PatternWidget.cxx
src/SMESHGUI/SMESHGUI_PrecisionDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ColorDlg.h
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.cxx
src/SMESHGUI/SMESHGUI_Preferences_ScalarBarDlg.h
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveElementsDlg.h
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.cxx
src/SMESHGUI/SMESHGUI_RemoveNodesDlg.h
src/SMESHGUI/SMESHGUI_RenumberingDlg.cxx
src/SMESHGUI/SMESHGUI_RenumberingDlg.h
src/SMESHGUI/SMESHGUI_RevolutionDlg.cxx
src/SMESHGUI/SMESHGUI_RevolutionDlg.h
src/SMESHGUI/SMESHGUI_RotationDlg.cxx
src/SMESHGUI/SMESHGUI_RotationDlg.h
src/SMESHGUI/SMESHGUI_Selection.cxx [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_Selection.h [new file with mode: 0644]
src/SMESHGUI/SMESHGUI_SewingDlg.cxx
src/SMESHGUI/SMESHGUI_SewingDlg.h
src/SMESHGUI/SMESHGUI_SingleEditDlg.cxx
src/SMESHGUI/SMESHGUI_SingleEditDlg.h
src/SMESHGUI/SMESHGUI_SmoothingDlg.cxx
src/SMESHGUI/SMESHGUI_SmoothingDlg.h
src/SMESHGUI/SMESHGUI_SpinBox.cxx
src/SMESHGUI/SMESHGUI_SpinBox.h
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.cxx
src/SMESHGUI/SMESHGUI_StandardMeshInfosDlg.h
src/SMESHGUI/SMESHGUI_Swig.cxx
src/SMESHGUI/SMESHGUI_SymmetryDlg.cxx
src/SMESHGUI/SMESHGUI_SymmetryDlg.h
src/SMESHGUI/SMESHGUI_TranslationDlg.cxx
src/SMESHGUI/SMESHGUI_TranslationDlg.h
src/SMESHGUI/SMESHGUI_TransparencyDlg.cxx
src/SMESHGUI/SMESHGUI_TransparencyDlg.h
src/SMESHGUI/SMESHGUI_Utils.cxx
src/SMESHGUI/SMESHGUI_Utils.h
src/SMESHGUI/SMESHGUI_VTKUtils.cxx
src/SMESHGUI/SMESHGUI_VTKUtils.h
src/SMESHGUI/SMESHGUI_XmlHandler.cxx
src/SMESHGUI/SMESHGUI_aParameter.cxx
src/SMESHGUI/SMESHGUI_aParameterDlg.cxx
src/SMESHGUI/SMESHGUI_aParameterDlg.h
src/SMESHGUI/SMESH_images.po [new file with mode: 0644]
src/SMESHGUI/SMESH_msg_en.po
src/SMESH_I/Makefile.in
src/SMESH_I/SMESH_DumpPython.cxx [new file with mode: 0644]
src/SMESH_I/SMESH_Filter_i.cxx
src/SMESH_I/SMESH_Filter_i.hxx
src/SMESH_I/SMESH_Gen_i.cxx
src/SMESH_I/SMESH_Gen_i.hxx
src/SMESH_I/SMESH_Group_i.cxx
src/SMESH_I/SMESH_Group_i.hxx
src/SMESH_I/SMESH_MEDFamily_i.hxx
src/SMESH_I/SMESH_MEDMesh_i.hxx
src/SMESH_I/SMESH_MeshEditor_i.cxx
src/SMESH_I/SMESH_MeshEditor_i.hxx
src/SMESH_I/SMESH_Mesh_i.cxx
src/SMESH_I/SMESH_Mesh_i.hxx
src/SMESH_I/SMESH_Pattern_i.cxx
src/SMESH_I/SMESH_Pattern_i.hxx
src/SMESH_I/SMESH_PythonDump.hxx [new file with mode: 0644]
src/SMESH_SWIG/Makefile.in
src/StdMeshers/StdMeshers_Quadrangle_2D.cxx
src/StdMeshersGUI/Makefile.in
src/StdMeshersGUI/StdMeshersGUI.cxx
src/StdMeshersGUI/StdMeshersGUI_CreateHypothesisDlg.cxx
src/StdMeshersGUI/StdMeshersGUI_CreateStdHypothesisDlg.cxx
src/StdMeshersGUI/StdMeshers_images.po [new file with mode: 0644]
src/StdMeshers_I/StdMeshers_Arithmetic1D_i.cxx
src/StdMeshers_I/StdMeshers_Deflection1D_i.cxx
src/StdMeshers_I/StdMeshers_LocalLength_i.cxx
src/StdMeshers_I/StdMeshers_MaxElementArea_i.cxx
src/StdMeshers_I/StdMeshers_MaxElementVolume_i.cxx
src/StdMeshers_I/StdMeshers_NumberOfSegments_i.cxx
src/StdMeshers_I/StdMeshers_StartEndLength_i.cxx

diff --git a/INSTALL b/INSTALL
index 72bd5f1..d9e6d95 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,6 @@
-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
index dfbd262..c659cb2 100644 (file)
@@ -53,6 +53,8 @@ mesh_line.png \
 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 \
index 5e2ad5b..e7e10c9 100644 (file)
@@ -67,7 +67,7 @@ QT_MT_LIBS = @QT_MT_LIBS@
 
 MOC = @MOC@
 UIC = @UIC@
-
+MSG2QM = @MSG2QM@
 
 #QWT
 
index 9eac1df..f4827fd 100644 (file)
@@ -327,11 +327,7 @@ distclean: clean
        $(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
index 44f7b56..e0c447a 100755 (executable)
@@ -1,2 +1,2 @@
-THIS IS SALOME - SMESH VERSION: 2.2.0
+THIS IS SALOME - SMESH VERSION: 3.0.0
 
index 2e65ed1..71cdbb9 100644 (file)
@@ -219,6 +219,14 @@ CHECK_QT
 
 echo
 echo ---------------------------------------------
+echo testing MSG2QM
+echo ---------------------------------------------
+echo
+
+CHECK_MSG2QM
+
+echo
+echo ---------------------------------------------
 echo testing VTK
 echo ---------------------------------------------
 echo
index 0644362..929afb6 100644 (file)
@@ -278,7 +278,7 @@ module SMESH
   /*!
   *  Filter
   */
-  interface Filter: SALOME::GenericObj
+  interface Filter: SALOME::GenericObj, SMESH_IDSource
   {
     /*!
     * Structure containing information about one criterion
@@ -312,6 +312,8 @@ module SMESH
     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();
index a39c344..3765767 100644 (file)
@@ -33,6 +33,8 @@
 
 module SMESH
 {
+  interface Predicate;
+
   /*!
    * SMESH_Group: base interface of group object
    */
@@ -98,11 +100,13 @@ module SMESH
      * 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 );
 
   };
   /*!
index e380a6a..53579df 100644 (file)
@@ -58,14 +58,17 @@ module SMESH
       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
     };
 
@@ -375,6 +378,9 @@ module SMESH
     long NbQuadrangles()
       raises (SALOME::SALOME_Exception);
 
+    long NbPolygons()
+      raises (SALOME::SALOME_Exception);
+
     long NbVolumes()
       raises (SALOME::SALOME_Exception);
 
@@ -390,6 +396,9 @@ module SMESH
     long NbPrisms()
       raises (SALOME::SALOME_Exception);
 
+    long NbPolyhedrons()
+      raises (SALOME::SALOME_Exception);
+
     long NbSubMesh()
       raises (SALOME::SALOME_Exception);
 
@@ -461,7 +470,7 @@ module SMESH
       raises (SALOME::SALOME_Exception);
   };
   
-  /* 
+  /*!
    * This interface makes modifications on the Mesh - removing elements and nodes etc.
    */
   interface NumericalFunctor;
@@ -480,6 +489,25 @@ module SMESH
 
     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);
@@ -521,6 +549,18 @@ module SMESH
                         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();
@@ -637,7 +677,9 @@ module SMESH
                               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,
@@ -649,7 +691,9 @@ module SMESH
                                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,
index fa1d7dd..d2324a0 100644 (file)
@@ -103,9 +103,15 @@ module SMESH
 
     /*!
      * 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
index 76072ee..e66eb08 100644 (file)
@@ -16,7 +16,7 @@
                <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>
index 0bbbc45..7d314c7 100644 (file)
      <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=""/>
diff --git a/resources/mesh_polygon.png b/resources/mesh_polygon.png
new file mode 100644 (file)
index 0000000..a1f671b
Binary files /dev/null and b/resources/mesh_polygon.png differ
diff --git a/resources/mesh_polyhedron.png b/resources/mesh_polyhedron.png
new file mode 100644 (file)
index 0000000..f475dec
Binary files /dev/null and b/resources/mesh_polyhedron.png differ
index 4aa92f1..3dd59cf 100644 (file)
@@ -81,7 +81,7 @@ namespace{
     return aDist;
   }
 
-  int getNbMultiConnection( SMDS_Mesh* theMesh, const int theId )
+  int getNbMultiConnection( const SMDS_Mesh* theMesh, const int theId )
   {
     if ( theMesh == 0 )
       return 0;
@@ -137,7 +137,7 @@ NumericalFunctor::NumericalFunctor():
   myPrecision = -1;
 }
 
-void NumericalFunctor::SetMesh( SMDS_Mesh* theMesh )
+void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
 }
@@ -213,26 +213,17 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
 {
   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;
 }
 
@@ -354,7 +345,7 @@ namespace{
     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])
@@ -638,8 +629,8 @@ double Warping::ComputeA( const gp_XYZ& thePnt1,
   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() )
@@ -771,12 +762,17 @@ SMDSAbs_ElementType Skew::GetType() const
 */
 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
@@ -1034,7 +1030,6 @@ double MultiConnection2D::GetValue( long theElementId )
   int aResult = 0;
   
   if (GetPoints(theElementId,P)){
-    double  aVal;
     const SMDS_MeshElement* anFaceElem = myMesh->FindElement( theElementId );
     SMDSAbs_ElementType aType = anFaceElem->GetType();
     
@@ -1116,7 +1111,6 @@ void MultiConnection2D::GetValues(MValues& theValues){
   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];
 
@@ -1176,7 +1170,7 @@ BadOrientedVolume::BadOrientedVolume()
   myMesh = 0;
 }
 
-void BadOrientedVolume::SetMesh( SMDS_Mesh* theMesh )
+void BadOrientedVolume::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
 }
@@ -1207,7 +1201,7 @@ FreeBorders::FreeBorders()
   myMesh = 0;
 }
 
-void FreeBorders::SetMesh( SMDS_Mesh* theMesh )
+void FreeBorders::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
 }
@@ -1232,7 +1226,7 @@ FreeEdges::FreeEdges()
   myMesh = 0;
 }
 
-void FreeEdges::SetMesh( SMDS_Mesh* theMesh )
+void FreeEdges::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
 }
@@ -1379,7 +1373,7 @@ RangeOfIds::RangeOfIds()
 // name    : SetMesh
 // Purpose : Set mesh 
 //=======================================================================
-void RangeOfIds::SetMesh( SMDS_Mesh* theMesh )
+void RangeOfIds::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
 }
@@ -1581,7 +1575,7 @@ Comparator::Comparator():
 Comparator::~Comparator()
 {}
 
-void Comparator::SetMesh( SMDS_Mesh* theMesh )
+void Comparator::SetMesh( const SMDS_Mesh* theMesh )
 {
   if ( myFunctor )
     myFunctor->SetMesh( theMesh );
@@ -1666,7 +1660,7 @@ bool LogicalNOT::IsSatisfy( long theId )
   return myPredicate && !myPredicate->IsSatisfy( theId );
 }
 
-void LogicalNOT::SetMesh( SMDS_Mesh* theMesh )
+void LogicalNOT::SetMesh( const SMDS_Mesh* theMesh )
 {
   if ( myPredicate )
     myPredicate->SetMesh( theMesh );
@@ -1693,7 +1687,7 @@ LogicalBinary::LogicalBinary()
 LogicalBinary::~LogicalBinary()
 {}
 
-void LogicalBinary::SetMesh( SMDS_Mesh* theMesh )
+void LogicalBinary::SetMesh( const SMDS_Mesh* theMesh )
 {
   if ( myPredicate1 )
     myPredicate1->SetMesh( theMesh );
@@ -1767,11 +1761,10 @@ void Filter::SetPredicate( PredicatePtr thePredicate )
   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() ) {
@@ -1783,40 +1776,46 @@ void FillSequence(const TIterator& theIterator,
   }
 }
 
-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);
 }
 
 /*
@@ -1880,7 +1879,7 @@ ManifoldPart::~ManifoldPart()
   myMesh = 0;
 }
 
-void ManifoldPart::SetMesh( SMDS_Mesh* theMesh )
+void ManifoldPart::SetMesh( const SMDS_Mesh* theMesh )
 {
   myMesh = theMesh;
   process();
@@ -2209,7 +2208,7 @@ ElementsOnSurface::~ElementsOnSurface()
   myMesh = 0;
 }
 
-void ElementsOnSurface::SetMesh( SMDS_Mesh* theMesh )
+void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh )
 { 
   if ( myMesh == theMesh )
     return;
index 339157e..02336eb 100644 (file)
@@ -97,14 +97,14 @@ namespace SMESH{
     {
     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;
@@ -117,7 +117,7 @@ namespace SMESH{
       static bool GetPoints(const SMDS_MeshElement* theElem, 
                            TSequenceOfXYZ& theRes);
     protected:
-      SMDS_Mesh* myMesh;
+      const SMDS_Mesh* myMesh;
       long       myPrecision;
     };
   
@@ -295,12 +295,12 @@ namespace SMESH{
     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;
     };
    
 
@@ -311,12 +311,12 @@ namespace SMESH{
     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;
     };
    
 
@@ -327,7 +327,7 @@ namespace SMESH{
     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  );
@@ -342,7 +342,7 @@ namespace SMESH{
       void GetBoreders(TBorders& theBorders);
       
     protected:
-      SMDS_Mesh* myMesh;
+      const SMDS_Mesh* myMesh;
     };
     typedef boost::shared_ptr<FreeEdges> FreeEdgesPtr;
 
@@ -359,7 +359,7 @@ namespace SMESH{
     {
     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 );
@@ -369,7 +369,7 @@ namespace SMESH{
       bool                          SetRangeStr( const TCollection_AsciiString& );
 
     protected:
-      SMDS_Mesh*                    myMesh;
+      const SMDS_Mesh*              myMesh;
 
       TColStd_SequenceOfInteger     myMin;
       TColStd_SequenceOfInteger     myMax;
@@ -389,7 +389,7 @@ namespace SMESH{
     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;
@@ -449,7 +449,7 @@ namespace SMESH{
       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;
   
@@ -467,7 +467,7 @@ namespace SMESH{
     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;
@@ -532,7 +532,7 @@ namespace SMESH{
       
       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;
@@ -560,7 +560,7 @@ namespace SMESH{
                               TVectorOfFacePtr& theFaces ) const;
 
     private:
-      SMDS_Mesh*            myMesh;
+      const SMDS_Mesh*      myMesh;
       TColStd_MapOfInteger  myMapIds;
       TColStd_MapOfInteger  myMapBadGeomIds;
       TVectorOfFacePtr      myAllFacePtr;
@@ -582,7 +582,7 @@ namespace SMESH{
     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;
 
@@ -597,7 +597,7 @@ namespace SMESH{
       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;
@@ -615,9 +615,20 @@ namespace SMESH{
       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;
     };
index 1433e32..1a00746 100644 (file)
@@ -268,7 +268,175 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
          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();
@@ -343,6 +511,8 @@ Driver_Mesh::Status DriverMED_R_SMESHDS_Mesh::Perform()
              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:
@@ -586,7 +756,7 @@ void DriverMED_R_SMESHDS_Mesh::GetGroup(SMESHDS_Group* theGroup)
       for (; anElemsIter != anElements.end(); anElemsIter++)
       {
         element = *anElemsIter;
-        theGroup->SMDSGroup().Add(element);
+       theGroup->SMDSGroup().Add(element);
       }
       if ( element )
         theGroup->SetType( element->GetType() );
index edd5418..82e134a 100644 (file)
@@ -33,6 +33,8 @@
 #include "SMESHDS_Mesh.hxx"
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+
 #include "utilities.h"
 
 #include "MED_Utilities.hxx"
@@ -61,7 +63,7 @@ void DriverMED_W_SMESHDS_Mesh::SetFile(const std::string& theFileName,
 
 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)
@@ -440,6 +442,16 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       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();
@@ -448,41 +460,42 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        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];
@@ -493,7 +506,13 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
          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())
@@ -523,6 +542,22 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        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
@@ -563,74 +598,111 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
       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]);
@@ -682,6 +754,23 @@ Driver_Mesh::Status DriverMED_W_SMESHDS_Mesh::Perform()
        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());
index 93c2cff..2064453 100644 (file)
 //  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 
     {
@@ -63,7 +36,8 @@ inline Standard_Integer HashCode
 
   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  : 
@@ -75,7 +49,32 @@ inline Standard_Boolean IsEqual
   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  : 
index bc91acb..8cf070c 100644 (file)
@@ -50,9 +50,9 @@ LIB_CLIENT_IDL = SALOME_Exception.idl \
 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@
index 004399a..3db87db 100644 (file)
@@ -31,9 +31,9 @@
 #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>
@@ -73,7 +73,7 @@
 #include "utilities.h"
 
 #ifdef _DEBUG_
-static int MYDEBUG = 0;
+static int MYDEBUG = 1;
 #else
 static int MYDEBUG = 0;
 #endif
@@ -118,7 +118,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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
   //-----------------------------------------
@@ -142,7 +142,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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);
@@ -154,13 +154,13 @@ SMESH_ActorDef::SMESH_ActorDef()
   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
   //---------------------------------
@@ -181,7 +181,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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();
@@ -206,7 +206,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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);
 
 
@@ -227,7 +227,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   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
@@ -288,38 +288,38 @@ SMESH_ActorDef::SMESH_ActorDef()
 
   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 );
@@ -327,74 +327,74 @@ SMESH_ActorDef::SMESH_ActorDef()
 
   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);
 
 
@@ -405,7 +405,7 @@ SMESH_ActorDef::SMESH_ActorDef()
   myPtsMaskPoints = vtkMaskPoints::New();
   myPtsMaskPoints->SetInput(myPointsNumDataSet);
   myPtsMaskPoints->SetOnRatio(1);
-    
+
   myPtsSelectVisiblePoints = vtkSelectVisiblePoints::New();
   myPtsSelectVisiblePoints->SetInput(myPtsMaskPoints->GetOutput());
   myPtsSelectVisiblePoints->SelectInvisibleOff();
@@ -623,7 +623,7 @@ SetControlMode(eControl theMode,
               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);
@@ -851,8 +851,9 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
   //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){
@@ -860,11 +861,11 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
   }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();
@@ -882,7 +883,7 @@ vtkDataSet* SMESH_ActorDef::GetInput(){
 }
 
 
-void SMESH_ActorDef::SetTransform(SALOME_Transform* theTransform){
+void SMESH_ActorDef::SetTransform(VTKViewer_Transform* theTransform){
   myNodeActor->SetTransform(theTransform);
   myBaseActor->SetTransform(theTransform);
 
@@ -1101,10 +1102,10 @@ void SMESH_ActorDef::SetEntityMode(unsigned int theMode){
   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");
@@ -1255,13 +1256,13 @@ void SMESH_ActorDef::UpdateHighlight(){
       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);
     }
   }
index dcb8d11..cc4345e 100644 (file)
@@ -29,7 +29,7 @@
 #ifndef SMESH_ACTOR_H
 #define SMESH_ACTOR_H
 
-#include "SALOME_Actor.h"
+#include <SALOME_Actor.h>
 #include "SMESH_Object.h"
 
 class vtkUnstructuredGrid;
index e6925d3..1928f65 100644 (file)
@@ -50,7 +50,7 @@ public:
     return *this;
   }
   TVTKSmartPtr& operator=(T* r){ vtkSmartPointer<T>::operator=(r); return *this;}
-  T* Get() const { return GetPointer();}
+  T* Get() const { return this->GetPointer();}
 };
 
 
@@ -147,7 +147,7 @@ class SMESH_ActorDef : public SMESH_Actor{
   virtual bool GetPointRepresentation();
 
   virtual float* GetBounds();
-  virtual void SetTransform(SALOME_Transform* theTransform); 
+  virtual void SetTransform(VTKViewer_Transform* theTransform); 
 
   virtual vtkUnstructuredGrid* GetUnstructuredGrid();
   virtual vtkDataSet* GetInput();
index fdaa86c..7e71257 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "SMESH_ActorUtils.h"
 
-#include "QAD_Config.h"
+//#include "QAD_Config.h"
 #include "utilities.h"
 
 #include <vtkUnstructuredGrid.h>
@@ -36,9 +36,10 @@ namespace SMESH{
 
   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){
index 962ad1e..3548aae 100644 (file)
 #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>
@@ -100,16 +100,16 @@ SMESH_DeviceActor::SMESH_DeviceActor()
   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());
 }
 
 
@@ -231,7 +231,7 @@ void SMESH_DeviceActor::SetUnstructuredGrid(vtkUnstructuredGrid* theGrid){
 }
 
 
-SALOME_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){
+VTKViewer_ExtractUnstructuredGrid* SMESH_DeviceActor::GetExtractUnstructuredGrid(){
   return myExtractUnstructuredGrid;
 }
 
@@ -300,7 +300,7 @@ void SMESH_DeviceActor::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor
   bool anIsInitialized = theFunctor;
   myExtractUnstructuredGrid->ClearRegisteredCells();
   myExtractUnstructuredGrid->ClearRegisteredCellsWithType();
-  myExtractUnstructuredGrid->SetModeOfChanging(SALOME_ExtractUnstructuredGrid::ePassAll);
+  myExtractUnstructuredGrid->SetModeOfChanging(VTKViewer_ExtractUnstructuredGrid::ePassAll);
   myVisualObj->UpdateFunctor(theFunctor);
 
   using namespace SMESH::Controls;
@@ -436,12 +436,12 @@ void SMESH_DeviceActor::SetExtControlMode(SMESH::Controls::FunctorPtr theFunctor
 {
   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++ ){
@@ -516,7 +516,7 @@ unsigned long int SMESH_DeviceActor::GetMTime(){
 }
 
 
-void SMESH_DeviceActor::SetTransform(SALOME_Transform* theTransform){
+void SMESH_DeviceActor::SetTransform(VTKViewer_Transform* theTransform){
   myTransformFilter->SetTransform(theTransform);
 }
 
index 96dd92c..88da39f 100644 (file)
@@ -29,7 +29,7 @@
 #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"
 
@@ -46,10 +46,10 @@ class vtkScalarBarActor;
 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;
 
@@ -71,7 +71,7 @@ class SMESH_DeviceActor: public vtkLODActor{
   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();
@@ -89,7 +89,7 @@ class SMESH_DeviceActor: public vtkLODActor{
   virtual void SetVisibility(int theMode);
   virtual int GetVisibility();
 
-  SALOME_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
+  VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
   vtkUnstructuredGrid* GetUnstructuredGrid();
 
   void SetControlMode(SMESH::Controls::FunctorPtr theFunctor,
@@ -122,12 +122,12 @@ class SMESH_DeviceActor: public vtkLODActor{
   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;
index 24023ba..885ee3d 100644 (file)
@@ -31,7 +31,7 @@
 #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)
 
@@ -160,6 +160,30 @@ namespace{
   }
 
 
+  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)
@@ -175,7 +199,7 @@ namespace{
                                                          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);
     }
   }
 
@@ -196,7 +220,7 @@ namespace{
                                                          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);
     }
   }
 
@@ -218,7 +242,7 @@ namespace{
                                                          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);
     }
   }
 
@@ -242,7 +266,69 @@ namespace{
                                                          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);
     }
   }
 
@@ -258,6 +344,7 @@ namespace{
 // purpose  : Get type of VTK cell
 //=================================================================================
 static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
+                                    const bool thePoly,
                                      const int theNbNodes )
 {
   switch( theType )
@@ -265,17 +352,19 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType 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;
   }
@@ -287,15 +376,12 @@ static inline vtkIdType getCellType( const SMDSAbs_ElementType theType,
 //=================================================================================
 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();
 }
 
@@ -545,35 +631,37 @@ void SMESH_VisualObjDef::buildElemPrs()
         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:
@@ -584,7 +672,7 @@ void SMESH_VisualObjDef::buildElemPrs()
        }
 
         aConnectivity->InsertNextCell( anIdList );
-        aCellTypesArray->InsertNextValue( getCellType( aType, aNbNodes ) );
+        aCellTypesArray->InsertNextValue( getCellType( aType, anElem->IsPoly(), aNbNodes ) );
 
         iElem++;
       }
@@ -628,7 +716,7 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
     
   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 ];
@@ -637,10 +725,10 @@ bool SMESH_VisualObjDef::GetEdgeNodes( const int theElemId,
   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
   {
@@ -697,25 +785,27 @@ void SMESH_MeshObj::Update( int theIsClear )
     
     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] ) );
@@ -743,8 +833,8 @@ void SMESH_MeshObj::Update( int theIsClear )
             // 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
@@ -752,6 +842,9 @@ void SMESH_MeshObj::Update( int theIsClear )
           }
           break;
 
+        case SMESH::CHANGE_POLYHEDRON_NODES:
+          ChangePolyhedronNodes(myMesh, aSeq, anId);
+          break;
         case SMESH::RENUMBER:
           for(CORBA::Long i=0; anElemId < aNbElems; anElemId++, i+=3)
           {
index 14df168..134b47b 100644 (file)
@@ -30,7 +30,7 @@
 #define SMESH_OBJECTDEF_H
 
 // IDL Headers
-#include "SALOMEconfig.h"
+#include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(SMESH_Mesh)
 #include CORBA_SERVER_HEADER(SMESH_Group)
 
index d64abd6..e066e25 100644 (file)
@@ -55,8 +55,10 @@ LIB_SRC = \
        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
@@ -107,8 +109,10 @@ EXPORT_HEADERS= \
        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
index 763d61c..0058da8 100644 (file)
@@ -29,6 +29,8 @@
 #include "SMDS_VolumeOfFaces.hxx"
 #include "SMDS_FaceOfNodes.hxx"
 #include "SMDS_FaceOfEdges.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+#include "SMDS_PolygonalFaceOfNodes.hxx"
 
 #include <algorithm>
 #include <map>
@@ -787,6 +789,126 @@ SMDS_MeshVolume* SMDS_Mesh::AddVolumeWithID(const SMDS_MeshFace * f1,
 }
 
 ///////////////////////////////////////////////////////////////////////////////
+/// 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)
@@ -966,10 +1088,25 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
   }
   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 )
@@ -1008,6 +1145,62 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
 }
 
 //=======================================================================
+//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  :
 //=======================================================================
@@ -1193,6 +1386,55 @@ const SMDS_MeshElement* SMDS_Mesh::FindElement(int IDelem) const
 }
 
 //=======================================================================
+//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  : 
 //=======================================================================
@@ -1743,7 +1985,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement *        elem,
   // 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);
@@ -1936,4 +2179,3 @@ void SMDS_Mesh::Renumber (const bool isNodes, const int  startID, const int  del
     ID += deltaID;
   }
 }
-
index 1aa9dda..9d59a3d 100644 (file)
@@ -201,6 +201,28 @@ public:
                                      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,
@@ -217,6 +239,9 @@ public:
   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.
@@ -235,6 +260,10 @@ public:
                                        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;
index 3d9d13a..b9f6135 100644 (file)
@@ -59,6 +59,8 @@ class SMDS_MeshElement:public SMDS_MeshObject
 
        ///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);
 
index 0acb246..0cb481c 100644 (file)
@@ -125,7 +125,7 @@ void SMDS_MeshGroup::Add(const SMDS_MeshElement * theElem)
        // 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);
 }
index 9631459..536b2f7 100644 (file)
@@ -44,8 +44,9 @@ int SMDS_MeshIDFactory::GetFreeID()
        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;
        }
 }
@@ -56,5 +57,27 @@ int SMDS_MeshIDFactory::GetFreeID()
 //=======================================================================
 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() );
+      }
+    }
+  }
 }
index 62b2d4c..8a6425a 100644 (file)
@@ -28,7 +28,7 @@
 #define _SMDS_MeshIDFactory_HeaderFile
 
 #include "SMDS_MeshObject.hxx"
-#include <stack>
+#include <set>
 
 
 class SMDS_MeshIDFactory:public SMDS_MeshObject
@@ -40,7 +40,7 @@ class SMDS_MeshIDFactory:public SMDS_MeshObject
   protected:
        SMDS_MeshIDFactory();
        int myMaxID;
-       std::stack<int> myPoolOfID;
+       std::set<int> myPoolOfID;
 };
 
 #endif
diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.cxx
new file mode 100644 (file)
index 0000000..38abf18
--- /dev/null
@@ -0,0 +1,174 @@
+//  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();
+}
diff --git a/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx b/src/SMDS/SMDS_PolygonalFaceOfNodes.hxx
new file mode 100644 (file)
index 0000000..5677462
--- /dev/null
@@ -0,0 +1,60 @@
+//  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
diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.cxx
new file mode 100644 (file)
index 0000000..8b26134
--- /dev/null
@@ -0,0 +1,182 @@
+//  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;
+}
diff --git a/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx b/src/SMDS/SMDS_PolyhedralVolumeOfNodes.hxx
new file mode 100644 (file)
index 0000000..d7cfeee
--- /dev/null
@@ -0,0 +1,72 @@
+//  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
index 0344868..dd98851 100644 (file)
 
 #include "SMDS_MeshElement.hxx"
 #include "SMDS_MeshNode.hxx"
+#include "SMDS_PolyhedralVolumeOfNodes.hxx"
+
+#include "utilities.h"
+
 #include <map>
 #include <float.h>
 #include <math.h>
@@ -200,19 +204,36 @@ double XYZ::Magnitude() {
 
 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 );
 }
@@ -224,6 +245,14 @@ SMDS_VolumeTool::SMDS_VolumeTool (const SMDS_MeshElement* theVolume)
 
 SMDS_VolumeTool::~SMDS_VolumeTool()
 {
+  if (myVolumeNodes != NULL) {
+    delete [] myVolumeNodes;
+    myVolumeNodes = NULL;
+  }
+  if (myFaceNodes != NULL) {
+    delete [] myFaceNodes;
+    myFaceNodes = NULL;
+  }
 }
 
 //=======================================================================
@@ -234,58 +263,75 @@ SMDS_VolumeTool::~SMDS_VolumeTool()
 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)           \
@@ -298,6 +344,11 @@ void SMDS_VolumeTool::Inverse ()
 {
   if ( !myVolume ) return;
 
+  if (myVolume->IsPoly()) {
+    MESSAGE("Warning: attempt to inverse polyhedral volume");
+    return;
+  }
+
   myVolForward = !myVolForward;
   myCurFace = -1;
 
@@ -372,9 +423,9 @@ void SMDS_VolumeTool::SetExternalNormal ()
 
 int SMDS_VolumeTool::NbFaceNodes( int faceIndex )
 {
-  if ( !setFace( faceIndex ))
-    return 0;
-  return myFaceNbNodes[ faceIndex ];
+    if ( !setFace( faceIndex ))
+      return 0;
+    return myFaceNbNodes;
 }
 
 //=======================================================================
@@ -402,6 +453,10 @@ const SMDS_MeshNode** SMDS_VolumeTool::GetFaceNodes( int faceIndex )
 
 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;
@@ -419,10 +474,10 @@ bool SMDS_VolumeTool::GetFaceNodes (int                        faceIndex,
     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;
 }
 
@@ -436,6 +491,16 @@ bool SMDS_VolumeTool::IsFaceExternal( int faceIndex )
   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:
@@ -482,7 +547,6 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
   return true;
 }
 
-
 //=======================================================================
 //function : GetFaceArea
 //purpose  : Return face area
@@ -490,6 +554,11 @@ bool SMDS_VolumeTool::GetFaceNormal (int faceIndex, double & X, double & Y, doub
 
 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;
 
@@ -500,7 +569,7 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
   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;
@@ -516,12 +585,17 @@ double SMDS_VolumeTool::GetFaceArea( int faceIndex )
 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;
@@ -542,6 +616,33 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
   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++ ) {
@@ -562,6 +663,10 @@ bool SMDS_VolumeTool::IsLinked (const SMDS_MeshNode* theNode1,
 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;
 
@@ -617,7 +722,6 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
   return -1;
 }
 
-
 //=======================================================================
 //function : IsFreeFace
 //purpose  : check that only one volume is build on the face nodes
@@ -626,11 +730,12 @@ int SMDS_VolumeTool::GetNodeIndex(const SMDS_MeshNode* theNode) const
 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;
@@ -706,7 +811,7 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex )
       // 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 ] ) &&
@@ -741,7 +846,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set<const SMDS_MeshNode*>& theFaceNodes
 //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 );
@@ -753,7 +858,7 @@ int SMDS_VolumeTool::GetFaceIndex( const set<int>& theFaceNodesIndices )
       return iFace;
   }
   return -1;
-}
+}*/
 
 //=======================================================================
 //function : setFace
@@ -768,44 +873,163 @@ bool SMDS_VolumeTool::setFace( int faceIndex )
   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;
+}
+
index 99e7dc1..89732b1 100644 (file)
@@ -32,6 +32,7 @@
 
 class SMDS_MeshElement;
 class SMDS_MeshNode;
+class SMDS_PolyhedralVolumeOfNodes;
 
 #include <vector>
 #include <set>
@@ -149,26 +150,52 @@ class SMDS_VolumeTool
   // 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
index e3bf98a..3084560 100644 (file)
@@ -79,7 +79,7 @@ static int MYDEBUG = 0;
 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;
@@ -97,7 +97,7 @@ SMESH_Mesh::SMESH_Mesh(int localId, int studyId, SMESH_Gen * gen, SMESHDS_Docume
 
 SMESH_Mesh::~SMESH_Mesh()
 {
-  INFOS("SMESH_Mesh::~SMESH_Mesh; this = "<<this);
+  INFOS("SMESH_Mesh::~SMESH_Mesh");
 
   // delete groups
   map < int, SMESH_Group * >::iterator itg;
@@ -660,6 +660,24 @@ throw(SALOME_Exception)
   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
@@ -833,7 +851,12 @@ int SMESH_Mesh::NbTriangles() throw(SALOME_Exception)
   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;
 }
 
@@ -846,7 +869,25 @@ int SMESH_Mesh::NbQuadrangles() throw(SALOME_Exception)
   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;
 }
 
@@ -866,7 +907,12 @@ int SMESH_Mesh::NbTetras() throw(SALOME_Exception)
   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;
 }
 
@@ -875,7 +921,12 @@ int SMESH_Mesh::NbHexas() throw(SALOME_Exception)
   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;
 }
 
@@ -884,7 +935,12 @@ int SMESH_Mesh::NbPyramids() throw(SALOME_Exception)
   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;
 }
 
@@ -893,7 +949,22 @@ int SMESH_Mesh::NbPrisms() throw(SALOME_Exception)
   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;
 }
 
@@ -992,8 +1063,8 @@ void SMESH_Mesh::RemoveGroup (const int theGroupID)
   if (_mapGroup.find(theGroupID) == _mapGroup.end())
     return;
   GetMeshDS()->RemoveGroup( _mapGroup[theGroupID]->GetGroupDS() );
-  delete _mapGroup[theGroupID];
   _mapGroup.erase (theGroupID);
+  delete _mapGroup[theGroupID];
 }
 
 //=============================================================================
index 2864dea..a91a886 100644 (file)
@@ -129,6 +129,9 @@ public:
   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);
@@ -165,6 +168,8 @@ public:
   int NbTriangles() throw(SALOME_Exception);
   
   int NbQuadrangles() throw(SALOME_Exception);
+
+  int NbPolygons() throw(SALOME_Exception);
   
   int NbVolumes() throw(SALOME_Exception);
   
@@ -173,9 +178,11 @@ public:
   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(); }
index dfc453b..94b59dc 100644 (file)
 
 #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;
 
@@ -494,11 +501,38 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem)
   }
   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:;
   }
@@ -977,12 +1011,12 @@ bool SMESH_MeshEditor::TriToQuad (set<const SMDS_MeshElement*> &       theElems,
 }
 
 
-#define DUMPSO(txt) \
+/*#define DUMPSO(txt) \
 //  cout << txt << endl;
 //=============================================================================
-/*!
- *
- */
+//
+//
+//
 //=============================================================================
 static void swap( int i1, int i2, int idNodes[], gp_Pnt P[] )
 {
@@ -1254,7 +1288,7 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
 //   }
 
   return true;
-}
+}*/
 
 //=======================================================================
 //function : laplacianSmooth
@@ -1262,52 +1296,76 @@ bool SMESH_MeshEditor::SortHexaNodes (const SMDS_Mesh * theMesh,
 //           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]);
 }
 
 //=======================================================================
@@ -1316,23 +1374,23 @@ void laplacianSmooth(SMESHDS_Mesh *                       theMesh,
 //           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.);
@@ -1343,6 +1401,11 @@ void centroidalSmooth(SMESHDS_Mesh *                       theMesh,
       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 );
@@ -1351,10 +1414,38 @@ void centroidalSmooth(SMESHDS_Mesh *                       theMesh,
     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;
 }
 
 //=======================================================================
@@ -1371,124 +1462,465 @@ void SMESH_MeshEditor::Smooth (set<const SMDS_MeshElement*> & theElems,
                                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
 }
 
 //=======================================================================
@@ -1593,6 +2025,8 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
     SMDS_MeshElement* aNewElem = 0;
     switch ( nbNodes )
     {
+    case 0:
+      return;
     case 1: { // NODE
       if ( nbSame == 0 )
         aNewElem = aMesh->AddEdge( prevNod[ 0 ], nextNod[ 0 ] );
@@ -1615,8 +2049,8 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
                                      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
@@ -1632,12 +2066,12 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
 
       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
@@ -1645,18 +2079,41 @@ static void sweepElement(SMESHDS_Mesh*                         aMesh,
         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 );
@@ -1790,6 +2247,16 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
               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
@@ -1818,6 +2285,17 @@ static void makeWalls (SMESHDS_Mesh*                 aMesh,
             !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;
       }
     }
 
@@ -2320,7 +2798,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     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() )
@@ -2334,8 +2812,12 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
       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
@@ -2386,6 +2868,82 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
     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 )
@@ -2499,6 +3057,88 @@ void SMESH_MeshEditor::FindCoincidentNodes (set<const SMDS_MeshNode*> & theNodes
 }
 
 //=======================================================================
+//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.
@@ -2572,6 +3212,88 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
     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;
@@ -2813,10 +3535,41 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes)
 
     } // 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
 
@@ -3091,7 +3844,9 @@ SMESH_MeshEditor::Sew_Error
                                    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;
@@ -3202,7 +3957,7 @@ SMESH_MeshEditor::Sew_Error
     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;
@@ -3230,6 +3985,7 @@ SMESH_MeshEditor::Sew_Error
         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
@@ -3313,7 +4069,7 @@ SMESH_MeshEditor::Sew_Error
     }
     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
     }
@@ -3437,15 +4193,19 @@ SMESH_MeshEditor::Sew_Error
           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 );
@@ -3485,18 +4245,22 @@ SMESH_MeshEditor::Sew_Error
       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
@@ -3515,14 +4279,15 @@ SMESH_MeshEditor::Sew_Error
 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() );
@@ -3541,11 +4306,12 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
 
   // 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();
@@ -3555,13 +4321,59 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
     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
@@ -3633,6 +4445,87 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement*     theFace,
 }
 
 //=======================================================================
+//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  : 
 //=======================================================================
@@ -3763,17 +4656,31 @@ SMESH_MeshEditor::Sew_Error
           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 );
index 677d9c0..0bb91f7 100644 (file)
@@ -98,13 +98,16 @@ class SMESH_MeshEditor {
                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,
@@ -154,6 +157,12 @@ class SMESH_MeshEditor {
   // 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.
@@ -189,7 +198,9 @@ class SMESH_MeshEditor {
                            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
@@ -226,20 +237,27 @@ class SMESH_MeshEditor {
   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,
index 0aeffec..fb9b5af 100644 (file)
@@ -58,6 +58,7 @@
 #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"
@@ -297,8 +298,8 @@ bool SMESH_Pattern::Load (const char* theFileContents)
 
   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 );
@@ -379,11 +380,11 @@ bool SMESH_Pattern::Save (ostream& theFile)
   }
   // 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;
@@ -594,8 +595,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
     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() )
       {
@@ -814,8 +815,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*        theMesh,
       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() ]);
       }
@@ -2456,7 +2457,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshFace* theFace,
                            const int            theNodeIndexOnKeyPoint1,
                            const bool           theReverse)
 {
-  MESSAGE(" ::Apply(MeshFace) " );
+//  MESSAGE(" ::Apply(MeshFace) " );
 
   if ( !IsLoaded() ) {
     MESSAGE( "Pattern not loaded" );
@@ -2610,89 +2611,15 @@ inline static bool isDefined(const gp_XYZ& theXYZ)
 }
 
 //=======================================================================
-//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>) " );
 
@@ -2710,10 +2637,13 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
     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() );
@@ -2723,11 +2653,6 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
   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
@@ -2741,37 +2666,45 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
     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 );
@@ -2779,8 +2712,6 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
     ind1 += myPoints.size();
   }
 
-  mergePoints( linkPointIndListMap, reverseConnectivity );
-
   return !myElemXYZIDs.empty();
 }
 
@@ -2793,9 +2724,9 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshFace*> theFaces,
 //           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>) " );
 
@@ -2813,10 +2744,13 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> theVolumes,
     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() );
@@ -2826,10 +2760,6 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> theVolumes,
   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
@@ -2843,27 +2773,28 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> theVolumes,
     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 );
@@ -2880,23 +2811,20 @@ bool SMESH_Pattern::Apply (std::set<const SMDS_MeshVolume*> theVolumes,
         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();
 }
 
@@ -3007,8 +2935,8 @@ bool SMESH_Pattern::Load (SMESH_Mesh*         theMesh,
     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() ]);
     }
@@ -3092,7 +3020,7 @@ bool SMESH_Pattern::Apply (const SMDS_MeshVolume* theVolume,
                            const int              theNode000Index,
                            const int              theNode001Index)
 {
-  MESSAGE(" ::Apply(MeshVolume) " );
+  //MESSAGE(" ::Apply(MeshVolume) " );
 
   if (!findBoundaryPoints()) // bind ID to points
     return false;
@@ -3130,19 +3058,431 @@ bool SMESH_Pattern::Apply (const SMDS_MeshVolume* theVolume,
 }
 
 //=======================================================================
+//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