Salome HOME
Implementation of task "3.1. Ability to export the PartSet to GEOM"
authormpv <mikhail.ponikarov@opencascade.com>
Thu, 16 May 2019 11:40:33 +0000 (14:40 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Thu, 16 May 2019 11:40:33 +0000 (14:40 +0300)
src/ConnectorAPI/Test/TestExportToGEOMPartSet.py [new file with mode: 0644]
src/ConnectorPlugin/ConnectorPlugin_ExportFeature.py
src/ConnectorPlugin/plugin-Connector.xml
src/ExchangePlugin/ExchangePlugin_ExportFeature.cpp
src/ExchangePlugin/ExchangePlugin_ExportFeature.h

diff --git a/src/ConnectorAPI/Test/TestExportToGEOMPartSet.py b/src/ConnectorAPI/Test/TestExportToGEOMPartSet.py
new file mode 100644 (file)
index 0000000..77d5478
--- /dev/null
@@ -0,0 +1,147 @@
+# Copyright (C) 2014-2019  CEA/DEN, EDF R&D
+#
+# 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, or (at your option) any later version.
+#
+# 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.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+
+import salome
+from ModelAPI import *
+from salome.shaper import model
+
+from salome.geom import geomBuilder
+
+import os
+import tempfile
+
+salome.salome_init(1)
+geompy = geomBuilder.New()
+
+## Get the last object published in the GEOM section of the object browser
+def getGEOMShape(index):
+  sb = salome.myStudy.NewBuilder()
+  comp = salome.myStudy.FindComponent("GEOM")
+  obj = None
+  if comp:
+    iterator = salome.myStudy.NewChildIterator( comp )
+    sobj = None
+    i = index + 1
+    while iterator.More() and i:
+      sobj = iterator.Value()
+      iterator.Next()
+      i = i - 1
+    if sobj:
+      obj = sobj.GetObject()
+  else:
+    raise Exception("GEOM component " + str(index) + " not found.")
+  return obj
+
+# create 4 parts:
+#  just an extrusiob
+#  extrusion with faces-group
+#  polyline with vertices-field
+#  part of one construction point
+
+model.begin()
+partSet = model.moduleDocument()
+Sketch_1 = model.addSketch(partSet, model.defaultPlane("XOY"))
+SketchLine_1 = Sketch_1.addLine(7, 0, 0, 0)
+SketchProjection_1 = Sketch_1.addProjection(model.selection("VERTEX", "Origin"), False)
+SketchPoint_1 = SketchProjection_1.createdFeature()
+SketchConstraintCoincidence_1 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchPoint_1.result())
+SketchLine_2 = Sketch_1.addLine(0, 0, 0, 9)
+SketchLine_3 = Sketch_1.addLine(0, 9, 7, 9)
+SketchLine_4 = Sketch_1.addLine(7, 9, 7, 0)
+SketchConstraintCoincidence_2 = Sketch_1.setCoincident(SketchLine_4.endPoint(), SketchLine_1.startPoint())
+SketchConstraintCoincidence_3 = Sketch_1.setCoincident(SketchLine_1.endPoint(), SketchLine_2.startPoint())
+SketchConstraintCoincidence_4 = Sketch_1.setCoincident(SketchLine_2.endPoint(), SketchLine_3.startPoint())
+SketchConstraintCoincidence_5 = Sketch_1.setCoincident(SketchLine_3.endPoint(), SketchLine_4.startPoint())
+SketchConstraintHorizontal_1 = Sketch_1.setHorizontal(SketchLine_1.result())
+SketchConstraintVertical_1 = Sketch_1.setVertical(SketchLine_2.result())
+SketchConstraintHorizontal_2 = Sketch_1.setHorizontal(SketchLine_3.result())
+SketchConstraintVertical_2 = Sketch_1.setVertical(SketchLine_4.result())
+SketchConstraintLength_1 = Sketch_1.setLength(SketchLine_3.result(), 7)
+SketchConstraintLength_2 = Sketch_1.setLength(SketchLine_4.result(), 9)
+SketchCircle_1 = Sketch_1.addCircle(3, 5, 2)
+SketchConstraintDistanceVertical_1 = Sketch_1.setVerticalDistance(SketchCircle_1.center(), SketchLine_1.startPoint(), 5)
+SketchConstraintDistanceHorizontal_1 = Sketch_1.setHorizontalDistance(SketchCircle_1.center(), SketchLine_1.endPoint(), 3)
+SketchConstraintRadius_1 = Sketch_1.setRadius(SketchCircle_1.results()[1], 2)
+model.do()
+Part_1 = model.addPart(partSet)
+Part_1_doc = Part_1.document()
+Extrusion_1 = model.addExtrusion(Part_1_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchLine_4r-SketchLine_3r-SketchLine_2r-SketchLine_1r-SketchCircle_1_2r")], model.selection(), 10, 0)
+model.do()
+Part_2 = model.addPart(partSet)
+Part_2_doc = Part_2.document()
+Extrusion_2 = model.addExtrusion(Part_2_doc, [model.selection("FACE", "PartSet/Sketch_1/Face-SketchCircle_1_2f")], model.selection(), 10, 0)
+Group_1 = model.addGroup(Part_2_doc, [model.selection("FACE", "Extrusion_1_1/Generated_Face&PartSet/Sketch_1/SketchCircle_1_2"), model.selection("FACE", "Extrusion_1_1/To_Face")])
+model.do()
+Part_3 = model.addPart(partSet)
+Part_3_doc = Part_3.document()
+Polyline_1_objects = [model.selection("VERTEX", "PartSet/Sketch_1/SketchLine_3_StartVertex"), model.selection("VERTEX", "PartSet/Sketch_1/SketchLine_4_EndVertex"), model.selection("VERTEX", "PartSet/Sketch_1/SketchLine_3_EndVertex")]
+Polyline_1 = model.addPolyline3D(Part_3_doc, Polyline_1_objects, True)
+Field_1_objects = [model.selection("VERTEX", "[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_3_StartVertex]e[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_4_EndVertex]e"), model.selection("VERTEX", "[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_4_EndVertex]e[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_3_EndVertex]e"), model.selection("VERTEX", "[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_3_StartVertex]e[Polyline_1_1/Generated_Edge&PartSet/Sketch_1/SketchLine_3_EndVertex]e")]
+Field_1 = model.addField(Part_3_doc, 2, "DOUBLE", 1, ["Comp 1"], Field_1_objects)
+Field_1.addStep(0, 0, [[1.5], [1.1], [2.4], [3]])
+Field_1.addStep(1, 2, [[1], [7], [5], [1.9]])
+model.do()
+Part_4 = model.addPart(partSet)
+Part_4_doc = Part_4.document()
+Point_2 = model.addPoint(Part_4_doc, model.selection("EDGE", "PartSet/Sketch_1/SketchCircle_1_2"))
+model.end()
+
+# Activate Partset to export to geom all Parts with group and filed where it is needed
+model.begin()
+aSession = ModelAPI_Session.get()
+partSet = aSession.moduleDocument()
+aSession.setActiveDocument(partSet, True)
+model.end()
+
+# export to GEOM
+model.begin()
+model.exportToGEOM(Part_1_doc)
+model.end()
+
+# check that in GEOM module there are reuslts:
+# extrusion of the first part
+# extrusion with group of the second part
+# extrusion with filed of the third part
+shape1 = getGEOMShape(0)
+assert(shape1)
+assert(shape1.GetName() == "Part_1")
+assert(geompy.NumberOfSolids(shape1) == 1)
+assert(not salome.ObjectToSObject(shape1).FindSubObject(1)[1])
+
+shape2 = getGEOMShape(1)
+assert(shape2)
+assert(shape2.GetName() == "Part_2")
+assert(geompy.NumberOfSolids(shape2) == 1)
+group = salome.ObjectToSObject(shape2).FindSubObject(1)[1].GetObject()
+assert(group)
+assert(group.GetName() == "Group_1")
+assert(geompy.NumberOfFaces(group) == 2)
+
+shape3 = getGEOMShape(2)
+assert(shape3)
+assert(shape3.GetName() == "Part_3")
+assert(geompy.NumberOfSolids(shape3) == 0)
+assert(geompy.NumberOfSubShapes(shape3, geompy.ShapeType["VERTEX"]) == 3)
+field = salome.ObjectToSObject(shape3).FindSubObject(1)[1].GetObject()
+assert(field)
+assert(field.GetName() == "Field_1")
+assert(field.GetSteps() == [0, 1])
+
+shape4 = getGEOMShape(3)
+assert(not shape4)
index 338161d4ae6bd77ee70a33858edd0be600eeeb0e..925b78c723fafbe5857941345f6b0fdc50a9014c 100644 (file)
@@ -22,6 +22,7 @@
 
 import ModelAPI
 import ExchangeAPI
+import EventsAPI
 
 import salome
 from salome.geom import geomBuilder
@@ -67,37 +68,52 @@ class ExportFeature(ModelAPI.ModelAPI_Feature):
 
     ## Export the results, groups and fields via XAO
     def exportViaXAO(self):
-        # iterate all results of Part, export one by one due to issue 2882
-        for aResIndex in range(self.Part.size(model.ModelAPI_ResultBody_group())):
-          anObject = self.Part.object(model.ModelAPI_ResultBody_group(), aResIndex)
-          aResult = model.objectToResult(anObject)
-          if not aResult is None:
-            tmpXAOFile = getTmpFileName("xao")
-            self.tmpXAOFile = tmpXAOFile
-            #print "Export to %s"%tmpXAOFile
-            exportXAO = ExchangeAPI.exportToXAO(self.Part, tmpXAOFile, model.selection(aResult), "automatic_shaper_export_to_XAO")
-            if not os.path.exists(tmpXAOFile) or os.stat(tmpXAOFile).st_size == 0:
-                exportXAO.feature().setError("Error in exportToXAO. No XAO file has been created.")
-                return
-            imported, shape, subShapes, groups, fields = self.geompy.ImportXAO(tmpXAOFile)
-            self.geompy.addToStudy( shape, shape.GetName() )
-            # add sub-shapes and groups to the object browser
-            for obj in subShapes + groups:
-                name = obj.GetName()
-                self.geompy.addToStudyInFather(shape, obj, name)
-            # add fields to the object browser
-            for field in fields:
-                name = field.GetName()
-                self.geompy.addToStudyInFather(shape, field, name)
-                # add steps to the object browser
-                steps = field.getSteps()
-                for i_step in steps:
-                    step = field.getStep(i_step)
-                    i_stamp = step.GetStamp()
-                    step_name = "Step %i %i"%(i_step, i_stamp)
-                    self.geompy.addToStudyInFather( field, step, step_name )
-            # Remove the temporary file
-            os.remove(tmpXAOFile)
+        # if part-set is active, iterate also parts
+        for isPart in (True, False):
+          aResultType = model.ModelAPI_ResultBody_group()
+          if isPart:
+            aResultType = model.ModelAPI_ResultPart_group()
+          # iterate all results of Part, export one by one due to issue 2882
+          for aResIndex in range(self.Part.size(aResultType)):
+            anObject = self.Part.object(aResultType, aResIndex)
+            aResult = model.objectToResult(anObject)
+            if not aResult is None:
+              if (not aResult.shape() or aResult.shape().isNull()) and isPart:
+                aPart = model.modelAPI_ResultPart(aResult)
+                aPartDoc = aPart.partDoc()
+                if not aPartDoc or not aPartDoc.isOpened():
+                  EventsAPI.Events_InfoMessage("ExportToGEOM", "For export to GEOM some Part is not activated", self).send()
+                  return
+
+              if  not aResult.shape() or aResult.shape().isNull():
+                continue
+              tmpXAOFile = getTmpFileName("xao")
+              self.tmpXAOFile = tmpXAOFile
+              #print "Export to %s"%tmpXAOFile
+              exportXAO = ExchangeAPI.exportToXAO(self.Part, tmpXAOFile, model.selection(aResult), "automatic_shaper_export_to_XAO")
+              if not os.path.exists(tmpXAOFile) or os.stat(tmpXAOFile).st_size == 0:
+                  exportXAO.feature().setError("Error in exportToXAO. No XAO file has been created.")
+                  return
+              imported, shape, subShapes, groups, fields = self.geompy.ImportXAO(tmpXAOFile)
+              self.geompy.addToStudy( shape, shape.GetName() )
+              # add sub-shapes and groups to the object browser
+              for obj in subShapes + groups:
+                  name = obj.GetName()
+                  self.geompy.addToStudyInFather(shape, obj, name)
+              # add fields to the object browser
+              for field in fields:
+                  name = field.GetName()
+                  self.geompy.addToStudyInFather(shape, field, name)
+                  # add steps to the object browser
+                  steps = field.getSteps()
+                  for i_step in steps:
+                      step = field.getStep(i_step)
+                      i_stamp = step.GetStamp()
+                      step_name = "Step %i %i"%(i_step, i_stamp)
+                      self.geompy.addToStudyInFather( field, step, step_name )
+              # Remove the temporary file
+              os.remove(tmpXAOFile)
+            pass
           pass
         pass
 
index 4ac52abae600627fd34198b5ea12ea26a679356b..caac05b282201cccb10641ccd8214ebd522b2395 100644 (file)
@@ -1,5 +1,5 @@
 <plugin>
-  <workbench id="Features" document="Part">
+  <workbench id="Features">
     <group id="Exchange">
       <feature
         id="ExportToGEOM"
index 30f690d1e241b26b1ace384424d33ca233688eee..688ffc03b289b9903822431dba9871bcc3c1ea33 100644 (file)
@@ -48,6 +48,7 @@
 #include <ModelAPI_Document.h>
 #include <ModelAPI_Object.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultPart.h>
 #include <ModelAPI_ResultGroup.h>
 #include <ModelAPI_ResultField.h>
 #include <ModelAPI_Session.h>
@@ -215,22 +216,45 @@ static std::string valToString(const ModelAPI_AttributeTables::Value& theVal,
 
 /// Returns true if something in selection is presented in the results list
 static bool isInResults(AttributeSelectionListPtr theSelection,
-                        const std::list<ResultBodyPtr>& theResults,
-                        std::set<ResultBodyPtr>& theCashedResults)
+                        const std::list<ResultPtr>& theResults,
+                        std::set<ResultPtr>& theCashedResults)
 {
   // collect all results into a cashed set
   if (theCashedResults.empty()) {
     std::list<ResultPtr> aResults;
-    std::list<ResultBodyPtr>::const_iterator aRes = theResults.cbegin();
+    std::list<ResultPtr>::const_iterator aRes = theResults.cbegin();
     for(; aRes != theResults.cend(); aRes++) {
       if (theCashedResults.count(*aRes))
         continue;
       else
         theCashedResults.insert(*aRes);
-      std::list<ResultPtr> aResults;
-      ModelAPI_Tools::allSubs(*aRes, aResults, false);
-      for(std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); aR++) {
-        theCashedResults.insert(std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aR));
+      if ((*aRes)->groupName() == ModelAPI_ResultBody::group()) {
+        ResultBodyPtr aResBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aRes);
+        std::list<ResultPtr> aResults;
+        ModelAPI_Tools::allSubs(aResBody, aResults, false);
+        for(std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); aR++) {
+          theCashedResults.insert(std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aR));
+        }
+      } else if ((*aRes)->groupName() == ModelAPI_ResultPart::group()) { // all results of the part
+        ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(*aRes);
+        DocumentPtr aPartDoc = aResPart->partDoc();
+        if (!aPartDoc.get() || !aPartDoc->isOpened()) { // document is not accessible
+          return false;
+        }
+        int aBodyCount = aPartDoc->size(ModelAPI_ResultBody::group());
+        for (int aBodyIndex = 0; aBodyIndex < aBodyCount; ++aBodyIndex) {
+          ResultBodyPtr aResBody =
+            std::dynamic_pointer_cast<ModelAPI_ResultBody>(
+              aPartDoc->object(ModelAPI_ResultBody::group(), aBodyIndex));
+          if (aResBody.get()) {
+            theCashedResults.insert(aResBody);
+            std::list<ResultPtr> aResults;
+            ModelAPI_Tools::allSubs(aResBody, aResults, false);
+            for(std::list<ResultPtr>::iterator aR = aResults.begin(); aR != aResults.end(); aR++) {
+              theCashedResults.insert(std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aR));
+            }
+          }
+        }
       }
     }
   }
@@ -258,21 +282,33 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
 
   // make shape for export from all results
   std::list<GeomShapePtr> aShapes;
-  std::list<ResultBodyPtr> aResults;
+  std::list<ResultPtr> aResults;
+  std::list<DocumentPtr> aDocuments; /// documents of Parts selected and used in export
 
   AttributeSelectionListPtr aSelection = selectionList(SELECTION_LIST_ID());
   bool aIsSelection = aSelection->isInitialized() && aSelection->size() > 0;
   if (aIsSelection) { // a mode for export to geom result by result
     for(int a = 0; a < aSelection->size(); a++) {
       AttributeSelectionPtr anAttr = aSelection->value(a);
-      ResultBodyPtr aBodyContext =
-        std::dynamic_pointer_cast<ModelAPI_ResultBody>(anAttr->context());
+      ResultPtr aBodyContext =
+        std::dynamic_pointer_cast<ModelAPI_Result>(anAttr->context());
       if (aBodyContext.get() && !aBodyContext->isDisabled() && aBodyContext->shape().get()) {
         aResults.push_back(aBodyContext);
         GeomShapePtr aShape = anAttr->value();
         if (!aShape.get())
           aShape = aBodyContext->shape();
         aShapes.push_back(aShape);
+        if (aBodyContext->groupName() == ModelAPI_ResultPart::group()) {
+          ResultPartPtr aResPart = std::dynamic_pointer_cast<ModelAPI_ResultPart>(aBodyContext);
+          DocumentPtr aPartDoc = aResPart->partDoc();
+          if (!aPartDoc.get() || !aPartDoc->isOpened()) { // document is not accessible
+            std::string msg = "Can not export XAO for not loaded part";
+            Events_InfoMessage("ExportFeature", msg, this).send();
+            return;
+          } else {
+            aDocuments.push_back(aPartDoc);
+          }
+        }
       }
     }
   } else {
@@ -308,165 +344,171 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
   std::string aGeometryName = string(ExchangePlugin_ExportFeature::XAO_GEOMETRY_NAME_ID())->value();
   if (aGeometryName.empty() && aResults.size() == 1) {
     // get the name from the first result
-    ResultBodyPtr aResultBody = *aResults.begin();
+    ResultPtr aResultBody = *aResults.begin();
     aGeometryName = aResultBody->data()->name();
   }
 
   aXao.getGeometry()->setName(aGeometryName);
 
-  std::set<ResultBodyPtr> allResultsCashed; // cash to speed up searching in all results selected
-
-  // groups
-  int aGroupCount = document()->size(ModelAPI_ResultGroup::group());
-  for (int aGroupIndex = 0; aGroupIndex < aGroupCount; ++aGroupIndex) {
-    ResultGroupPtr aResultGroup =
-        std::dynamic_pointer_cast<ModelAPI_ResultGroup>(
-            document()->object(ModelAPI_ResultGroup::group(), aGroupIndex));
+  std::set<ResultPtr> allResultsCashed; // cash to speed up searching in all results selected
 
-    FeaturePtr aGroupFeature = document()->feature(aResultGroup);
+  // iterate all documents used
+  if (aDocuments.empty())
+    aDocuments.push_back(document());
+  std::list<DocumentPtr>::iterator aDoc = aDocuments.begin();
+  for(; aDoc != aDocuments.end(); aDoc++) {
+    // groups
+    int aGroupCount = (*aDoc)->size(ModelAPI_ResultGroup::group());
+    for (int aGroupIndex = 0; aGroupIndex < aGroupCount; ++aGroupIndex) {
+      ResultGroupPtr aResultGroup = std::dynamic_pointer_cast<ModelAPI_ResultGroup>(
+          (*aDoc)->object(ModelAPI_ResultGroup::group(), aGroupIndex));
 
-    AttributeSelectionListPtr aSelectionList =
-        aGroupFeature->selectionList("group_list");
+      FeaturePtr aGroupFeature = (*aDoc)->feature(aResultGroup);
 
-    if (!isInResults(aSelectionList, aResults, allResultsCashed))// skip group not used in results
-      continue;
+      AttributeSelectionListPtr aSelectionList =
+          aGroupFeature->selectionList("group_list");
+      if (!isInResults(aSelectionList, aResults, allResultsCashed))// skip group not used in result
+        continue;
 
-    // conversion of dimension
-    std::string aSelectionType = aSelectionList->selectionType();
-    std::string aDimensionString =
-      ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
-    XAO::Dimension aGroupDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
+      // conversion of dimension
+      std::string aSelectionType = aSelectionList->selectionType();
+      std::string aDimensionString =
+        ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
+      XAO::Dimension aGroupDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
 
-    XAO::Group* aXaoGroup = aXao.addGroup(aGroupDimension,
-                                          aResultGroup->data()->name());
+      XAO::Group* aXaoGroup = aXao.addGroup(aGroupDimension,
+                                            aResultGroup->data()->name());
 
-    try {
-      for (int aSelectionIndex = 0; aSelectionIndex < aSelectionList->size(); ++aSelectionIndex) {
-        AttributeSelectionPtr aSelection = aSelectionList->value(aSelectionIndex);
+      try {
+        for (int aSelectionIndex = 0; aSelectionIndex < aSelectionList->size(); ++aSelectionIndex){
+          AttributeSelectionPtr aSelection = aSelectionList->value(aSelectionIndex);
 
-        // complex conversion of reference id to element index
-        // gives bad id in case the selection is done from python script
-        // => using GeomAlgoAPI_CompoundBuilder::id instead
-        // int aReferenceID_old = aSelection->Id();
+          // complex conversion of reference id to element index
+          // gives bad id in case the selection is done from python script
+          // => using GeomAlgoAPI_CompoundBuilder::id instead
+          // int aReferenceID_old = aSelection->Id();
 
-        int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
+          int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
 
-        if (aReferenceID == 0) // selected value does not found in the exported shape
-          continue;
+          if (aReferenceID == 0) // selected value does not found in the exported shape
+            continue;
 
-        std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
-        int anElementID =
-          aXao.getGeometry()->getElementIndexByReference(aGroupDimension, aReferenceString);
+          std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
+          int anElementID =
+            aXao.getGeometry()->getElementIndexByReference(aGroupDimension, aReferenceString);
 
-        aXaoGroup->add(anElementID);
+          aXaoGroup->add(anElementID);
+        }
+      } catch (XAO::XAO_Exception& e) {
+        // LCOV_EXCL_START
+        std::string msg = "An error occurred while exporting group " +
+          aResultGroup->data()->name();
+        msg += ".\n";
+        msg += e.what();
+        msg += "\n";
+        msg += "=> skipping this group from XAO export.";
+        Events_InfoMessage("ExportFeature", msg, this).send();
+        aXao.removeGroup(aXaoGroup);
+        // LCOV_EXCL_STOP
       }
-    } catch (XAO::XAO_Exception& e) {
-      // LCOV_EXCL_START
-      std::string msg = "An error occurred while exporting group " + aResultGroup->data()->name();
-      msg += ".\n";
-      msg += e.what();
-      msg += "\n";
-      msg += "=> skipping this group from XAO export.";
-      Events_InfoMessage("ExportFeature", msg, this).send();
-      aXao.removeGroup(aXaoGroup);
-      // LCOV_EXCL_STOP
     }
-  }
 
-  // fields
-  int aFieldCount = document()->size(ModelAPI_ResultField::group());
-  for (int aFieldIndex = 0; aFieldIndex < aFieldCount; ++aFieldIndex) {
-    ResultFieldPtr aResultField =
-        std::dynamic_pointer_cast<ModelAPI_ResultField>(
-            document()->object(ModelAPI_ResultField::group(), aFieldIndex));
-
-    FeaturePtr aFieldFeature = document()->feature(aResultField);
-
-    AttributeSelectionListPtr aSelectionList =
-        aFieldFeature->selectionList("selected");
-    std::string aSelectionType = aSelectionList->selectionType();
-    bool isWholePart = aSelectionType == "part";
-
-    if (!isWholePart &&
-        !isInResults(aSelectionList, aResults, allResultsCashed))// skip field not used in results
-      continue;
-
-    // conversion of dimension
-    std::string aDimensionString =
-      ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
-    XAO::Dimension aFieldDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
-    // get tables and their type
-    std::shared_ptr<ModelAPI_AttributeTables> aTables = aFieldFeature->tables("values");
-    std::string aTypeString = ExchangePlugin_Tools::valuesType2xaoType(aTables->type());
-    XAO::Type aFieldType = XAO::XaoUtils::stringToFieldType(aTypeString);
-
-    XAO::Field* aXaoField = aXao.addField(aFieldType, aFieldDimension, aTables->columns(),
-                                          aResultField->data()->name());
-
-
-    try {
-      // set components names
-      AttributeStringArrayPtr aComponents = aFieldFeature->stringArray("components_names");
-      for(int aComp = 0; aComp < aComponents->size(); aComp++) {
-        std::string aName = aComponents->value(aComp);
-        aXaoField->setComponentName(aComp, aName);
-      }
+    // fields
+    int aFieldCount = (*aDoc)->size(ModelAPI_ResultField::group());
+    for (int aFieldIndex = 0; aFieldIndex < aFieldCount; ++aFieldIndex) {
+      ResultFieldPtr aResultField = std::dynamic_pointer_cast<ModelAPI_ResultField>(
+        (*aDoc)->object(ModelAPI_ResultField::group(), aFieldIndex));
 
-      AttributeIntArrayPtr aStamps = aFieldFeature->intArray("stamps");
-      for (int aStepIndex = 0; aStepIndex < aTables->tables(); aStepIndex++) {
-        XAO::Step* aStep = aXaoField->addNewStep(aStepIndex);
-        aStep->setStep(aStepIndex);
-        int aStampIndex = aStamps->value(aStepIndex);
-        aStep->setStamp(aStampIndex);
-        int aNumElements = isWholePart ? aXaoField->countElements() : aTables->rows();
-        int aNumComps = aTables->columns();
-        std::set<int> aFilledIDs; // to fill the rest by defaults
-        // omit default values first row
-        for(int aRow = isWholePart ? 0 : 1; aRow < aNumElements; aRow++) {
-          for(int aCol = 0; aCol < aNumComps; aCol++) {
-            int anElementID = 0;
-            if (!isWholePart) {
-              // element index actually is the ID of the selection
-              AttributeSelectionPtr aSelection = aSelectionList->value(aRow - 1);
-              int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
-              if (aReferenceID == 0) // selected value does not found in the exported shape
-                continue;
+      FeaturePtr aFieldFeature = (*aDoc)->feature(aResultField);
 
-              std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
-              anElementID =
-                aXao.getGeometry()->getElementIndexByReference(aFieldDimension, aReferenceString);
-            }
+      AttributeSelectionListPtr aSelectionList =
+          aFieldFeature->selectionList("selected");
+      std::string aSelectionType = aSelectionList->selectionType();
+      bool isWholePart = aSelectionType == "part";
+      // skip field not used in results
+      if (!isWholePart && !isInResults(aSelectionList, aResults, allResultsCashed))
+        continue;
 
-            ModelAPI_AttributeTables::Value aVal = aTables->value(
-              isWholePart ? 0 : aRow, aCol, aStepIndex);
-            std::string aStrVal = valToString(aVal, aTables->type());
-            aStep->setStringValue(isWholePart ? aRow : anElementID, aCol, aStrVal);
-            aFilledIDs.insert(anElementID);
-          }
+      // conversion of dimension
+      std::string aDimensionString =
+        ExchangePlugin_Tools::selectionType2xaoDimension(aSelectionType);
+      XAO::Dimension aFieldDimension = XAO::XaoUtils::stringToDimension(aDimensionString);
+      // get tables and their type
+      std::shared_ptr<ModelAPI_AttributeTables> aTables = aFieldFeature->tables("values");
+      std::string aTypeString = ExchangePlugin_Tools::valuesType2xaoType(aTables->type());
+      XAO::Type aFieldType = XAO::XaoUtils::stringToFieldType(aTypeString);
+
+      XAO::Field* aXaoField = aXao.addField(aFieldType, aFieldDimension, aTables->columns(),
+                                            aResultField->data()->name());
+
+
+      try {
+        // set components names
+        AttributeStringArrayPtr aComponents = aFieldFeature->stringArray("components_names");
+        for(int aComp = 0; aComp < aComponents->size(); aComp++) {
+          std::string aName = aComponents->value(aComp);
+          aXaoField->setComponentName(aComp, aName);
         }
-        if (!isWholePart) { // fill the rest values by default ones
-          XAO::GeometricElementList::iterator allElem = aXao.getGeometry()->begin(aFieldDimension);
-          for(; allElem != aXao.getGeometry()->end(aFieldDimension); allElem++) {
-            if (aFilledIDs.find(allElem->first) != aFilledIDs.end())
-              continue;
+
+        AttributeIntArrayPtr aStamps = aFieldFeature->intArray("stamps");
+        for (int aStepIndex = 0; aStepIndex < aTables->tables(); aStepIndex++) {
+          XAO::Step* aStep = aXaoField->addNewStep(aStepIndex);
+          aStep->setStep(aStepIndex);
+          int aStampIndex = aStamps->value(aStepIndex);
+          aStep->setStamp(aStampIndex);
+          int aNumElements = isWholePart ? aXaoField->countElements() : aTables->rows();
+          int aNumComps = aTables->columns();
+          std::set<int> aFilledIDs; // to fill the rest by defaults
+          // omit default values first row
+          for(int aRow = isWholePart ? 0 : 1; aRow < aNumElements; aRow++) {
             for(int aCol = 0; aCol < aNumComps; aCol++) {
-              ModelAPI_AttributeTables::Value aVal = aTables->value(0, aCol, aStepIndex); // default
+              int anElementID = 0;
+              if (!isWholePart) {
+                // element index actually is the ID of the selection
+                AttributeSelectionPtr aSelection = aSelectionList->value(aRow - 1);
+                int aReferenceID = GeomAlgoAPI_CompoundBuilder::id(aShape, aSelection->value());
+                if (aReferenceID == 0) // selected value does not found in the exported shape
+                  continue;
+
+                std::string aReferenceString = XAO::XaoUtils::intToString(aReferenceID);
+                anElementID = aXao.getGeometry()->
+                  getElementIndexByReference(aFieldDimension, aReferenceString);
+              }
+
+              ModelAPI_AttributeTables::Value aVal = aTables->value(
+                isWholePart ? 0 : aRow, aCol, aStepIndex);
               std::string aStrVal = valToString(aVal, aTables->type());
-              aStep->setStringValue(allElem->first, aCol, aStrVal);
+              aStep->setStringValue(isWholePart ? aRow : anElementID, aCol, aStrVal);
+              aFilledIDs.insert(anElementID);
+            }
+          }
+          if (!isWholePart) { // fill the rest values by default ones
+            XAO::GeometricElementList::iterator allElem =
+              aXao.getGeometry()->begin(aFieldDimension);
+            for(; allElem != aXao.getGeometry()->end(aFieldDimension); allElem++) {
+              if (aFilledIDs.find(allElem->first) != aFilledIDs.end())
+                continue;
+              for(int aCol = 0; aCol < aNumComps; aCol++) {
+                // default value
+                ModelAPI_AttributeTables::Value aVal = aTables->value(0, aCol, aStepIndex);
+                std::string aStrVal = valToString(aVal, aTables->type());
+                aStep->setStringValue(allElem->first, aCol, aStrVal);
+              }
             }
           }
         }
+      } catch (XAO::XAO_Exception& e) {
+        // LCOV_EXCL_START
+        std::string msg = "An error occurred while exporting field " +
+          aResultField->data()->name();
+        msg += ".\n";
+        msg += e.what();
+        msg += "\n";
+        msg += "=> skipping this field from XAO export.";
+        Events_InfoMessage("ExportFeature", msg, this).send();
+        aXao.removeField(aXaoField);
+        // LCOV_EXCL_STOP
       }
-    } catch (XAO::XAO_Exception& e) {
-      // LCOV_EXCL_START
-      std::string msg = "An error occurred while exporting field " + aResultField->data()->name();
-      msg += ".\n";
-      msg += e.what();
-      msg += "\n";
-      msg += "=> skipping this field from XAO export.";
-      Events_InfoMessage("ExportFeature", msg, this).send();
-      aXao.removeField(aXaoField);
-      // LCOV_EXCL_STOP
     }
   }
 
@@ -486,3 +528,32 @@ void ExchangePlugin_ExportFeature::exportXAO(const std::string& theFileName)
   }
 // LCOV_EXCL_STOP
 }
+
+bool ExchangePlugin_ExportFeature::isMacro() const
+{
+  if (!data().get() || !data()->isValid())
+    return false;
+  ExchangePlugin_ExportFeature* aThis = ((ExchangePlugin_ExportFeature*)(this));
+  AttributeStringPtr aFormatAttr = aThis->string(FILE_FORMAT_ID());
+  if (!aFormatAttr.get())
+    return false;
+  std::string aFormat = aFormatAttr->value();
+
+  if (aFormat.empty()) { // get default format for the extension
+    AttributeStringPtr aFilePathAttr = aThis->string(FILE_PATH_ID());
+    std::string aFilePath = aFilePathAttr->value();
+    if (!aFilePath.empty()) {
+      std::string anExtension = GeomAlgoAPI_Tools::File_Tools::extension(aFilePath);
+      if (anExtension == "XAO") {
+        aFormat = "XAO";
+      }
+    }
+  }
+
+  if (aFormat == "XAO") { // on export to GEOm the selection attribute is filled - this is
+                          // an exceptional case where export to XAO feature must be kept
+    AttributeSelectionListPtr aList = aThis->selectionList(SELECTION_LIST_ID());
+    return !aList->isInitialized() || aList->size() == 0;
+  }
+  return true;
+}
index 3644a37b4c4ad6457738e86d37422dba84ff221a..c0a79a8c5ea092bcbbba0d7fff00d3a97f0d6d7a 100644 (file)
@@ -105,8 +105,9 @@ public:
   EXCHANGEPLUGIN_EXPORT virtual void execute();
 
   /// Reimplemented from ModelAPI_Feature::isMacro(). Returns false.
-  // Not a macro. Otherwise, the feature will be deleted after being executed
-  EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const { return false; }
+  // It is macro for not-XAO export. For XAO the feature is kept invisible in the tree
+  // for the export to GEOM functionality correct working.
+  EXCHANGEPLUGIN_EXPORT virtual bool isMacro() const;
 
   /// Reimplemented from ModelAPI_Feature::isPreviewNeeded(). Returns false.
   EXCHANGEPLUGIN_EXPORT virtual bool isPreviewNeeded() const { return false; }