]> SALOME platform Git repositories - modules/geom.git/commitdiff
Salome HOME
0023216: [CEA 1691] Import the compounds with their names from a STEP file
authorskv <skv@opencascade.com>
Tue, 16 Feb 2016 14:19:14 +0000 (17:19 +0300)
committerskv <skv@opencascade.com>
Tue, 16 Feb 2016 14:19:14 +0000 (17:19 +0300)
15 files changed:
idl/STEPPlugin.idl
src/GEOM_I_Superv/GEOM_Superv_i.cc
src/GEOM_SWIG/STEPPluginBuilder.py
src/STEPPlugin/CMakeLists.txt
src/STEPPlugin/STEPPlugin_GUI.cxx
src/STEPPlugin/STEPPlugin_IECallBack.cxx
src/STEPPlugin/STEPPlugin_IImport.hxx
src/STEPPlugin/STEPPlugin_IOperations.cxx
src/STEPPlugin/STEPPlugin_IOperations.hxx
src/STEPPlugin/STEPPlugin_IOperations_i.cc
src/STEPPlugin/STEPPlugin_IOperations_i.hh
src/STEPPlugin/STEPPlugin_ImportDlg.cxx [new file with mode: 0644]
src/STEPPlugin/STEPPlugin_ImportDlg.h [new file with mode: 0644]
src/STEPPlugin/STEPPlugin_ImportDriver.cxx
src/STEPPlugin/STEPPlugin_msg_en.ts

index ba1a74ec8b919b16a24be4c6d81adf3e95868766..9caf6f373de9f7f56cc13f498d83967eacbf6917 100644 (file)
@@ -64,10 +64,14 @@ module GEOM
      *  \param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter')
      *                          and result model will be scaled, if its units are not meters.
      *                          If False (default), file length units will be taken into account.
+     *  \param IsCreateAssemblies If True, for each assembly compound is created
+     *                          in the result. If False Compounds that contain a
+     *                          single shape are eliminated from the result.
      *  \return List of GEOM_Objects, containing the created shape and propagation groups.
      */              
     GEOM::ListOfGO ImportSTEP( in string  theFileName,
-                               in boolean theIsIgnoreUnits );
+                               in boolean theIsIgnoreUnits,
+                               in boolean IsCreateAssemblies);
                                
     /*!
      *  \brief Read a value of parameter from a file, containing a shape.
index 662b2c76894adc3b0ed7a71bda8a0135934908eb..a229accac0d38b3b3ea09457abd7728d664277fc 100644 (file)
@@ -3579,7 +3579,7 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::ImportSTEP( const char* theFileName,
   beginService( " GEOM_Superv_i::ImportSTEP" );
   MESSAGE("GEOM_Superv_i::ImportSTEP");
   getSTEPPluginOp();
-  GEOM::ListOfGO* aSeq = mySTEPOp->ImportSTEP(theFileName, theIsIgnoreUnits );
+  GEOM::ListOfGO* aSeq = mySTEPOp->ImportSTEP(theFileName, theIsIgnoreUnits, false );
   GEOM::GEOM_Object_ptr anObj;
 
   if (aSeq->length() > 0) {
index 1ee4fc6c79a8d9f6c62150d482e1e682807e6400..896c0f7d6b6bc2a53af8568759b51e48a8da28e0 100644 (file)
@@ -54,6 +54,9 @@ def ExportSTEP(self, theObject, theFileName, theUnit=GEOM.LU_METER):
 #  @param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter')
 #         and result model will be scaled, if its units are not meters.
 #         If False (default), file length units will be taken into account.
+#  @param IsCreateAssemblies If True, for each assembly compound is created in
+#         the result. If False Compounds that contain a single shape
+#         are eliminated from the result.
 #  @param theName Object name; when specified, this parameter is used
 #         for result publication in the study. Otherwise, if automatic
 #         publication is switched on, default value is used for result name.
@@ -67,7 +70,8 @@ def ExportSTEP(self, theObject, theFileName, theUnit=GEOM.LU_METER):
 #
 #  @ref swig_Import_Export "Example"
 #  @ingroup l2_import_export
-def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None):
+def ImportSTEP(self, theFileName, theIsIgnoreUnits = False,
+               IsCreateAssemblies = False, theName=None):
     """
     Import a shape from the STEP file with given name.
 
@@ -76,6 +80,9 @@ def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None):
         ignoreUnits If True, file length units will be ignored (set to 'meter')
                     and result model will be scaled, if its units are not meters.
                     If False (default), file length units will be taken into account.
+        IsCreateAssemblies If True, for each assembly compound is created in
+                    the result. If False Compounds that contain a single shape
+                    are eliminated from the result.
         theName Object name; when specified, this parameter is used
                 for result publication in the study. Otherwise, if automatic
                 publication is switched on, default value is used for result name.
@@ -94,13 +101,18 @@ def ImportSTEP(self, theFileName, theIsIgnoreUnits = False, theName=None):
     anOp = GetSTEPPluginOperations(self)
     
     anIsIgnoreUnits = theIsIgnoreUnits
+    anIsCreateAssemblies = IsCreateAssemblies;
     aName = theName
     if isinstance( theIsIgnoreUnits, basestring ):
         anIsIgnoreUnits = False
         aName = theIsIgnoreUnits
         pass
+    elif isinstance( IsCreateAssemblies, basestring ):
+        anIsCreateAssemblies = False
+        aName = IsCreateAssemblies
+        pass
 
-    aListObj = anOp.ImportSTEP(theFileName,anIsIgnoreUnits)
+    aListObj = anOp.ImportSTEP(theFileName,anIsIgnoreUnits,anIsCreateAssemblies)
     RaiseIfFailed("ImportSTEP", anOp)
     aNbObj = len(aListObj)
     if aNbObj > 0:
index db71d3b2454b5828df5a42b44ad73970340acc3e..efd69970aba81519c25b9083e73e19764f657b2f 100644 (file)
@@ -94,6 +94,7 @@ SET(STEPPluginEngine_HEADERS
   STEPPlugin_IExport.hxx 
   STEPPlugin_IImport.hxx
   STEPPlugin_ImportDriver.hxx 
+  STEPPlugin_ImportDlg.h
   STEPPlugin_ExportDlg.h
   STEPPlugin_ExportDriver.hxx
   STEPPlugin_IECallBack.hxx
@@ -104,6 +105,7 @@ IF(SALOME_BUILD_GUI)
   SET(_moc_HEADERS
     STEPPlugin_GUI.h
     STEPPlugin_ExportDlg.h
+    STEPPlugin_ImportDlg.h
     )
 ENDIF()
 
@@ -116,6 +118,7 @@ IF(SALOME_BUILD_GUI)
   SET(STEPPluginGUI_SOURCES
     STEPPlugin_GUI.cxx
     STEPPlugin_ExportDlg.cxx
+    STEPPlugin_ImportDlg.cxx
     ${_moc_SOURCES}
     )
 ENDIF()
index 5543266d7845b41240aee421f25afd0948132210..2986dea4b49525dae101125ed90f9a955e589ae1 100644 (file)
@@ -38,6 +38,7 @@
 #include "GEOM_Displayer.h"
 #include "GEOM_GenericObjPtr.h"
 #include "STEPPlugin_ExportDlg.h"
+#include "STEPPlugin_ImportDlg.h"
 
 #include <SALOMEconfig.h>
 #include CORBA_SERVER_HEADER(STEPPlugin)
@@ -118,10 +119,11 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent )
   STEPOpPtr stepOp = GEOM::ISTEPOperations::_narrow( op );
   if ( stepOp.isNull() ) return false;
 
-  QStringList fileNames = app->getOpenFileNames( SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""),
-                                                tr( "STEP_FILES" ),
-                                                tr( "IMPORT_TITLE" ),
-                                                parent );
+  bool        isCreateAssemblies = true;
+  QStringList fileNames          = STEPPlugin_ImportDlg::getOpenFileNames
+        (SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : QString(""),
+         tr("STEP_FILES"), tr("IMPORT_TITLE"), parent, isCreateAssemblies);
+
   if ( fileNames.count() > 0 )
   {
     QStringList entryList;
@@ -175,7 +177,8 @@ bool STEPPlugin_GUI::importSTEP( SUIT_Desktop* parent )
          }
        }
        
-       GEOM::ListOfGO_var result = stepOp->ImportSTEP( fileName.toUtf8().constData(), ignoreUnits );
+       GEOM::ListOfGO_var result = stepOp->ImportSTEP
+          (fileName.toUtf8().constData(), ignoreUnits, isCreateAssemblies);
        if ( result->length() > 0 && stepOp->IsDone() )
        {
          GEOM::GEOM_Object_var main = result[0];
index ac08697164d4d722623bc28b5d16aec8f69ab1a1..b745f0d048623e360315161781281f0bc525e248 100644 (file)
@@ -70,7 +70,7 @@ STEPPlugin_IECallBack::Import( int                            theDocId,
 {
   STEPPlugin_IOperations* aPluginOperations = STEPPlugin_OperationsCreator::get( GetEngine(), theDocId );
   bool anIsIgnoreUnits = ( theFormatName == "STEP_SCALE" ) ? true : false;
-  return aPluginOperations->ImportSTEP( theFileName, anIsIgnoreUnits );
+  return aPluginOperations->ImportSTEP( theFileName, anIsIgnoreUnits, false );
 }
 
 //=============================================================================
index 3b63fdfdc4c185a6cde0822fd137deacf98ebe62..f7630e4ebb2fcb84d8e79d0fc953173a7dfdb35c 100644 (file)
@@ -22,8 +22,9 @@
 
 #include "GEOM_Function.hxx"
 
-#define IMPORTSTEP_ARG_FILENAME     1
-#define IMPORTSTEP_ARG_IGNORE_UNITS 2
+#define IMPORTSTEP_ARG_FILENAME          1
+#define IMPORTSTEP_ARG_IGNORE_UNITS      2
+#define IMPORTSTEP_ARG_CREATE_ASSEMBLIES 3
 
 class STEPPlugin_IImport
 {
@@ -41,6 +42,12 @@ public:
   bool GetIsIgnoreUnits()
     { return bool( _func->GetInteger( IMPORTSTEP_ARG_IGNORE_UNITS ) ); }
 
+  void SetIsCreateAssemblies( bool IsCreateAssemblies )
+  { _func->SetInteger
+        ( IMPORTSTEP_ARG_CREATE_ASSEMBLIES, IsCreateAssemblies ? 1 : 0 ); }
+  bool GetIsCreateAssemblies()
+    { return ( _func->GetInteger( IMPORTSTEP_ARG_CREATE_ASSEMBLIES ) != 0 ); }
+
 private:
   Handle(GEOM_Function) _func;
 };
index 72064e8e3027fb780a0dd0518e3babec2d149d95..24f898aeb6d4a65fd802337a3c84d8789f16cedd 100644 (file)
@@ -167,8 +167,9 @@ void STEPPlugin_IOperations::ExportSTEP
  */
 //=============================================================================
 Handle(TColStd_HSequenceOfTransient)
-STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName,
-                                   const bool theIsIgnoreUnits )
+STEPPlugin_IOperations::ImportSTEP(const TCollection_AsciiString& theFileName,
+                                   const bool theIsIgnoreUnits,
+                                   const bool IsCreateAssemblies)
 {
   SetErrorCode(KO);
   if( theFileName.IsEmpty() ) return NULL;
@@ -188,6 +189,7 @@ STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName,
   STEPPlugin_IImport aCI( aFunction );
   aCI.SetFileName( theFileName );
   aCI.SetIsIgnoreUnits( theIsIgnoreUnits );
+  aCI.SetIsCreateAssemblies( IsCreateAssemblies );
 
   //Perform the Import
   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
@@ -211,10 +213,10 @@ STEPPlugin_IOperations::ImportSTEP( const TCollection_AsciiString& theFileName,
 
   //Make a Python command
   GEOM::TPythonDump pd (aFunction);
-  if( theIsIgnoreUnits )
-    pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)";
-  else
-    pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")";
+  pd << aSeq << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", ";
+  pd << (theIsIgnoreUnits ? "True" : "False");
+  pd << ", " << (IsCreateAssemblies ? "True" : "False");
+  pd << ")";
   SetErrorCode(OK);
 
   return aSeq;
index 92b3f160e78430fde83aa5b926f8557f17890de6..90266d34b565c433013d04c9edd45bfd79d8ba37 100644 (file)
@@ -57,8 +57,9 @@ public:
   void ExportSTEP( const Handle(GEOM_Object),
                   const TCollection_AsciiString&, const LengthUnit );
   
-  Handle(TColStd_HSequenceOfTransient) ImportSTEP( const TCollection_AsciiString&,
-                                                  const bool );
+  Handle(TColStd_HSequenceOfTransient) ImportSTEP(const TCollection_AsciiString&,
+                                                  const bool,
+                                                  const bool);
   
   TCollection_AsciiString ReadValue( const TCollection_AsciiString&,
                                     const TCollection_AsciiString& );
index fba3ce031e4fd7c2a2ea5d0cf282d4dde8df3daa..fa40dae0edb86c7df582b43757ea69ce76259b13 100644 (file)
@@ -119,11 +119,16 @@ void STEPPlugin_IOperations_i::ExportSTEP(GEOM::GEOM_Object_ptr theOriginal,
  *  \param theIsIgnoreUnits If True, file length units will be ignored (set to 'meter')
  *                          and result model will be scaled, if its units are not meters.
  *                          If False (default), file length units will be taken into account.
+ *  \param IsCreateAssemblies If True, for each assembly compound is created
+ *                          in the result. If False Compounds that contain a
+ *                          single shape are eliminated from the result.
  *  \return List of GEOM_Objects, containing the created shape and propagation groups.
  */
 //=============================================================================
-GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP( const char* theFileName,
-                                                     const bool  theIsIgnoreUnits = false )
+GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP
+                          (const char *theFileName,
+                           const bool  theIsIgnoreUnits,
+                           const bool  IsCreateAssemblies)
 {
   GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO;
 
@@ -131,7 +136,8 @@ GEOM::ListOfGO* STEPPlugin_IOperations_i::ImportSTEP( const char* theFileName,
   GetOperations()->SetNotDone();
 
   //Import the shape from the file
-  Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->ImportSTEP( theFileName, theIsIgnoreUnits );
+  Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->ImportSTEP
+    (theFileName, theIsIgnoreUnits, IsCreateAssemblies);
 
   if( !GetOperations()->IsDone() || aHSeq.IsNull() )
     return aSeq._retn();
index 16e000909c8b134ce81573a3bd0640a06e789606..4faa4128cb1f35c04c8232e46b7b648d5aebb372 100644 (file)
@@ -45,7 +45,7 @@ public:
 
   void            ExportSTEP( GEOM::GEOM_Object_ptr, const char*,
                               GEOM::length_unit );
-  GEOM::ListOfGO* ImportSTEP( const char*, const bool );
+  GEOM::ListOfGO* ImportSTEP( const char*, const bool, const bool );
   char*           ReadValue( const char*, const char* );
 
   STEPPlugin_IOperations* GetOperations();
diff --git a/src/STEPPlugin/STEPPlugin_ImportDlg.cxx b/src/STEPPlugin/STEPPlugin_ImportDlg.cxx
new file mode 100644 (file)
index 0000000..de6cb21
--- /dev/null
@@ -0,0 +1,94 @@
+// Copyright (C) 2014-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+#include "STEPPlugin_ImportDlg.h"
+
+#include <QApplication>
+#include <QLayout>
+#include <QCheckBox>
+
+//=============================================================================
+// Constructor
+//=============================================================================
+STEPPlugin_ImportDlg::STEPPlugin_ImportDlg(QWidget *parent)
+  : SUIT_FileDlg (parent, true, true, true),
+    myCheckBox   (0)
+{
+  myCheckBox = new QCheckBox(tr("STEP_CREATE_ASSEMBLIES"), this);
+
+  myCheckBox->setChecked(true);
+
+  layout()->addWidget(myCheckBox);
+}
+
+//=============================================================================
+// Destructor
+//=============================================================================
+STEPPlugin_ImportDlg::~STEPPlugin_ImportDlg()
+{
+}
+
+//=============================================================================
+// IsCreateAssemblies
+//=============================================================================
+bool STEPPlugin_ImportDlg::IsCreateAssemblies() const
+{
+  return myCheckBox->isChecked();
+}
+
+//=============================================================================
+// getOpenFileNames
+//=============================================================================
+QStringList STEPPlugin_ImportDlg::getOpenFileNames
+                                  (const QString &theInitial,
+                                   const QString &theFilters,
+                                   const QString &theCaption,
+                                         QWidget *theParent,
+                                         bool    &IsCreateAssemblies)
+{
+  STEPPlugin_ImportDlg anImpDlg(theParent);
+  QStringList aFilters = theFilters.split(";;", QString::SkipEmptyParts);
+
+  anImpDlg.setFileMode(ExistingFiles);
+
+  if (aFilters.isEmpty()) {
+    anImpDlg.setFilter(tr("ALL_FILES_FILTER")); // All files (*)
+  } else {
+    anImpDlg.setFilters(aFilters);
+  }
+
+  if (!theCaption.isEmpty()) {
+    anImpDlg.setWindowTitle(theCaption);
+  }
+
+  if (!theInitial.isEmpty()) {
+    anImpDlg.processPath(theInitial);
+  }
+
+  QStringList aFileNames;
+
+  if (anImpDlg.exec() == QDialog::Accepted) {
+    aFileNames = anImpDlg.selectedFiles();
+    IsCreateAssemblies = anImpDlg.IsCreateAssemblies();
+  }
+
+  QApplication::processEvents();
+
+  return aFileNames;
+}
diff --git a/src/STEPPlugin/STEPPlugin_ImportDlg.h b/src/STEPPlugin/STEPPlugin_ImportDlg.h
new file mode 100644 (file)
index 0000000..32f75d3
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright (C) 2014-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// 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
+//
+
+#ifndef STEPPlugin_ImportDlg_H
+#define STEPPlugin_ImportDlg_H
+
+#include <SUIT_FileDlg.h>
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(STEPPlugin)
+
+class QCheckBox;
+
+class STEPPlugin_ImportDlg: public SUIT_FileDlg
+{
+  Q_OBJECT
+
+public:
+
+  STEPPlugin_ImportDlg(QWidget *parent);
+  ~STEPPlugin_ImportDlg();
+
+  bool IsCreateAssemblies() const;
+
+  static QStringList getOpenFileNames (const QString    &theInitial,
+                                       const QString    &theFilters,
+                                       const QString    &theCaption,
+                                             QWidget    *theParent,
+                                             bool       &IsCreateAssemblies);
+
+private:
+
+  QCheckBox *myCheckBox;
+
+};
+
+#endif // STEPPlugin_ImportDlg_H
index 961dd77be42d117980a790b60ce9cea2300b2fbe..1cf37959d7eba4502be09f39ba7a7248f41f8497 100644 (file)
@@ -47,6 +47,7 @@
 #include <StepGeom_GeometricRepresentationItem.hxx>
 #include <StepShape_TopologicalRepresentationItem.hxx>
 #include <StepRepr_DescriptiveRepresentationItem.hxx>
+#include <StepRepr_NextAssemblyUsageOccurrence.hxx>
 #include <StepRepr_ProductDefinitionShape.hxx>
 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
 #include <StepRepr_Representation.hxx>
 #include <BRep_Builder.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_MapOfShape.hxx>
 #include <TopoDS_Compound.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TColStd_SequenceOfAsciiString.hxx>
@@ -139,22 +144,227 @@ namespace
     return aResult;
   }
 
+  //=============================================================================
+  /*!
+   *  GetAllParents()
+   */
+  //=============================================================================
+
+  Standard_Boolean GetAllParents(const TopoDS_Shape         &theShape,
+                                 const TopoDS_Shape         &theSubShape,
+                                       TopTools_ListOfShape &theParents)
+  {
+    const TopAbs_ShapeEnum aSubShType = theSubShape.ShapeType();
+    Standard_Boolean       aResult    = Standard_False;
+
+    if (theShape.ShapeType() >= aSubShType) {
+      return aResult; // NULL shape
+    }
+
+    TopoDS_Iterator     anIt(theShape);
+    TopTools_MapOfShape aMapFence;
+
+    for (; anIt.More(); anIt.Next()) {
+      const TopoDS_Shape &aSubShape = anIt.Value();
+
+      if (aMapFence.Add(aSubShape)) {
+        if (theSubShape.IsSame(aSubShape)) {
+          // The sub-shape is found. theShape is its parent.
+          theParents.Append(theShape);
+          aResult = Standard_True;
+          break;
+        }
+
+        if (aSubShape.ShapeType() < aSubShType) {
+          if (GetAllParents(aSubShape, theSubShape, theParents)) {
+            // The sub-shape is found.
+            theParents.Append(theShape);
+            aResult = Standard_True;
+            break;
+          }
+        }
+      }
+    }
+
+    return aResult;
+  }
+
+  //=============================================================================
+  /*!
+   *  BuildModifiedShape()
+   */
+  //=============================================================================
+
+  TopoDS_Shape BuildModifiedShape
+              (const TopoDS_Shape                 &theShape,
+                     TopTools_DataMapOfShapeShape &theMapModified)
+  {
+    // Check if the shape is modified.
+    TopoDS_Shape     aFwdShape  = theShape.Oriented(TopAbs_FORWARD);
+    TopoDS_Iterator  anIt(aFwdShape);
+    Standard_Boolean isModified = Standard_False;
+
+    for (; anIt.More(); anIt.Next()) {
+      if (theMapModified.IsBound(anIt.Value())) {
+        isModified = Standard_True;
+        break;
+      }
+    }
+
+    TopoDS_Shape aResult;
+
+    if (isModified) {
+      BRep_Builder aBuilder;
+
+      aResult = aFwdShape.EmptyCopied();
+
+      for (anIt.Initialize(aFwdShape); anIt.More(); anIt.Next()) {
+        const TopoDS_Shape &aSubShape = anIt.Value();
+
+        if (theMapModified.IsBound(aSubShape)) {
+          TopoDS_Shape aModifSubShape = theMapModified.Find(aSubShape);
+
+          if (aModifSubShape.IsNull()) {
+            // Recursively compute the sub-shape.
+            aModifSubShape = BuildModifiedShape(aSubShape, theMapModified);
+          }
+
+          aBuilder.Add(aResult, aModifSubShape);
+        } else {
+          aBuilder.Add(aResult, aSubShape);
+        }
+      }
+
+      // Set the result shape orienation.
+      aResult.Orientation(theShape.Orientation());
+      theMapModified.Bind(theShape, aResult);
+    } else {
+      aResult = theShape;
+    }
+
+    return aResult;
+  }
+
+  //=============================================================================
+  /*!
+   *  CreateAssemblies()
+   */
+  //=============================================================================
+
+  TopoDS_Shape CreateAssemblies
+              (const STEPControl_Reader           &theReader,
+               const TopoDS_Shape                 &theShape,
+                     TopTools_DataMapOfShapeShape &theMapShapeAssembly)
+  {
+    TopoDS_Shape                     aResult = theShape;
+    Handle(XSControl_TransferReader) aTR     = theReader.WS()->TransferReader();
+    TopTools_ListOfShape             aListAssemblies;
+
+    if (!aTR.IsNull()) {
+      Handle(Interface_InterfaceModel)  aModel      = theReader.WS()->Model();
+      Handle(Transfer_TransientProcess) aTP         = aTR->TransientProcess();
+      Standard_Integer                  aNbEntities = aModel->NbEntities();
+      Standard_Integer                  i;
+      Handle(Standard_Type)             aNAUOType   =
+              STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence);
+
+      for (i = 1; i <= aNbEntities; i++) {
+        Handle(Standard_Transient) anEnti = aModel->Value(i);
+
+        if (anEnti->IsKind(aNAUOType)) {
+          // This is an assembly. Find target shape
+          TopoDS_Shape aShape = GetShape(anEnti, aTP);
+
+          if (aShape.IsNull()) {
+            continue;
+          }
+
+          if (aShape.ShapeType() != TopAbs_COMPOUND) {
+            aListAssemblies.Append(aShape);
+          }
+        }
+      }
+    }
+
+    // Create assemblies.
+    if (!aListAssemblies.IsEmpty()) {
+      TopTools_ListIteratorOfListOfShape anIter(aListAssemblies);
+      BRep_Builder                       aBuilder;
+
+      for (; anIter.More(); anIter.Next()) {
+        const TopoDS_Shape   &aShape  = anIter.Value();
+        TopTools_ListOfShape  aParents;
+
+        if (GetAllParents(theShape, aShape, aParents) &&
+            aParents.First().ShapeType() == TopAbs_COMPOUND) {
+          TopoDS_Compound                    aComp;
+          TopTools_ListIteratorOfListOfShape aParentIter(aParents);
+
+          // Fill theMapShapeAssembly.
+          for (; aParentIter.More(); aParentIter.Next()) {
+            theMapShapeAssembly.Bind(aParentIter.Value(), TopoDS_Shape());
+          }
+
+          aBuilder.MakeCompound(aComp);
+          aBuilder.Add(aComp, aShape);
+          theMapShapeAssembly.Bind(aShape, aComp);
+        }
+      }
+
+      // Build a new shape.
+      aResult = BuildModifiedShape(theShape, theMapShapeAssembly);
+    }
+
+    return aResult;
+  }
+
   //=============================================================================
   /*!
    *  StoreName()
    */
   //=============================================================================
   
-  void StoreName( const Handle(Standard_Transient)        &theEnti,
-                  const TopTools_IndexedMapOfShape        &theIndices,
-                  const Handle(Transfer_TransientProcess) &theTP,
-                  const TDF_Label                         &theShapeLabel)
+  void StoreName(const Handle(Standard_Transient)        &theEnti,
+                 const TopTools_IndexedMapOfShape        &theIndices,
+                 const Handle(XSControl_WorkSession)     &theWS,
+                 const Handle(Transfer_TransientProcess) &theTP,
+                 const TDF_Label                         &theShapeLabel,
+                       TopTools_DataMapOfShapeShape      &theMapShapeAssembly)
   {
     Handle(TCollection_HAsciiString) aName;
     
     if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) ||
         theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
       aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name();
+    } else if (theEnti->IsKind(STANDARD_TYPE(StepRepr_NextAssemblyUsageOccurrence))) {
+      Handle(StepRepr_NextAssemblyUsageOccurrence) aNAUO = 
+        Handle(StepRepr_NextAssemblyUsageOccurrence)::DownCast(theEnti);
+
+      Interface_EntityIterator aSubs = theWS->Graph().Sharings(aNAUO);
+
+      for (aSubs.Start(); aSubs.More(); aSubs.Next()) {
+        Handle(StepRepr_ProductDefinitionShape) aPDS = 
+          Handle(StepRepr_ProductDefinitionShape)::DownCast(aSubs.Value());
+
+        if(aPDS.IsNull()) {
+          continue;
+        }
+
+        Handle(StepBasic_ProductDefinitionRelationship) aPDR =
+          aPDS->Definition().ProductDefinitionRelationship();
+
+        if (aPDR.IsNull()) {
+          continue;
+        }
+
+        if (aPDR->HasDescription() && aPDR->Description()->Length() >0) {
+          aName = aPDR->Description();
+        } else if (!aPDR->Name().IsNull() && aPDR->Name()->Length() >0 ) {
+          aName = aPDR->Name();
+        } else if (!aPDR->Id().IsNull()) {
+          aName = aPDR->Id();
+        }
+      }
     } else {
       Handle(StepBasic_ProductDefinition) PD =
         Handle(StepBasic_ProductDefinition)::DownCast(theEnti);
@@ -198,6 +408,10 @@ namespace
       // find target shape
       TopoDS_Shape S = GetShape(theEnti, theTP);
 
+      if (theMapShapeAssembly.IsBound(S)) {
+        S = theMapShapeAssembly.Find(S);
+      }
+
       if (S.IsNull()) {
         return;
       }
@@ -392,6 +606,7 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons
 
   TCollection_AsciiString aFileName = aData.GetFileName().ToCString();
   bool anIsIgnoreUnits = aData.GetIsIgnoreUnits();
+  bool isCreateAssemblies = aData.GetIsCreateAssemblies();
   TDF_Label aShapeLabel = aFunction->GetNamingEntry();
 
   MESSAGE("Import STEP from file " << aFileName.ToCString() );
@@ -439,48 +654,91 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons
       aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
 
       // Root transfers
-      Standard_Integer nbr = aReader.NbRootsForTransfer();
+      Standard_Integer aNbRoots = aReader.NbRootsForTransfer();
+      Standard_Integer i;
+
       aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
 
-      for (Standard_Integer n = 1; n <= nbr; n++) {
-        Standard_Boolean ok = aReader.TransferRoot(n);
-        // Collecting resulting entities
-        Standard_Integer nbs = aReader.NbShapes();
-        if (!ok || nbs == 0)
-          continue; // skip empty root
-
-        // For a single entity
-        else if (nbr == 1 && nbs == 1) {
-          aResShape = aReader.Shape(1);
-          if (aResShape.ShapeType() == TopAbs_COMPOUND) {
-            int nbSub1 = 0;
-            TopoDS_Shape currShape;
-            TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
-            for (; It.More(); It.Next()) {
-              nbSub1++;
-              currShape = It.Value();
-            }
-            if (nbSub1 == 1)
-              aResShape = currShape;
+      for (i = 1; i <= aNbRoots; i++) {
+        aReader.TransferRoot(i);
+      }
+
+      // Create result shape
+      const Standard_Integer aNbShapes = aReader.NbShapes();
+      TopTools_ListOfShape   aListResShapes;
+
+      if (isCreateAssemblies) {
+        for (i = 1; i <= aNbShapes; i++) {
+          TopoDS_Shape aShape = aReader.Shape(i);
+
+          if (aShape.IsNull()) {
+            continue;
           }
-          break;
-        }
 
-        for (Standard_Integer i = 1; i <= nbs; i++) {
+          aListResShapes.Append(aShape);
+        }
+      } else {
+        for (i = 1; i <= aNbShapes; i++) {
           TopoDS_Shape aShape = aReader.Shape(i);
-          if (aShape.IsNull())
+
+          if (aShape.IsNull()) {
             continue;
-          else
-            B.Add(compound, aShape);
+          }
+
+          if (aShape.ShapeType() == TopAbs_COMPOUND) {
+            int             aNbSub = 0;
+            TopoDS_Shape    aSubShape;
+            TopoDS_Iterator anIt (aShape, Standard_True, Standard_True);
+
+            for (; anIt.More(); anIt.Next()) {
+              aNbSub++;
+              aSubShape = anIt.Value();
+            }
+
+            if (aNbSub == 1) {
+              // Use the single sub-shape
+              aListResShapes.Append(aSubShape);
+            } else if (aNbSub > 1) {
+              // Use the shape
+              aListResShapes.Append(aShape);
+            }
+          }
+        }
+      }
+
+      // Construct result shape.
+      if (!aListResShapes.IsEmpty()) {
+        if (aListResShapes.Extent() == 1) {
+          // Use the single shape.
+          aResShape = aListResShapes.First();
+        } else {
+          // Make a compound of result shapes.
+          TopTools_ListIteratorOfListOfShape anIt(aListResShapes);
+
+          for (; anIt.More(); anIt.Next()) {
+            B.Add(compound, anIt.Value());
+          }
+
+          aResShape = compound;
         }
       }
-      if( aResShape.IsNull() )
-        aResShape = compound;
+
+      if( aResShape.IsNull() ) {
+        StdFail_NotDone::Raise("Null result shape");
+        return 0;
+      }
 
       // Check if any BRep entity has been read, there must be at least a vertex
       if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
         StdFail_NotDone::Raise( "No geometrical data in the imported file." );
 
+      // Create assemblies in the shape, if they are not created yet.
+      TopTools_DataMapOfShapeShape aMapShapeAssembly;
+
+      if (isCreateAssemblies) {
+        aResShape = CreateAssemblies(aReader, aResShape, aMapShapeAssembly);
+      }
+
       // BEGIN: Store names and materials of sub-shapes from file
       TopTools_IndexedMapOfShape anIndices;
       TopExp::MapShapes(aResShape, anIndices);
@@ -496,7 +754,8 @@ Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) cons
           Handle(Standard_Transient) enti = Model->Value(ie);
 
           // Store names.
-          StoreName(enti, anIndices, TP, aShapeLabel);
+          StoreName(enti, anIndices, aReader.WS(),
+                    TP, aShapeLabel, aMapShapeAssembly);
 
           // Store materials.
           StoreMaterial(enti, anIndices, TP, aShapeLabel);
@@ -575,6 +834,7 @@ GetCreationInformation( std::string&             theOperationName,
     AddParam( theParams, "File name", aCI.GetFileName() );
     if( aCI.GetIsIgnoreUnits() )
       AddParam( theParams, "Format", "STEP_SCALE" );
+    AddParam( theParams, "Create Assemblies", aCI.GetIsCreateAssemblies() );
     break;
   default:
     return false;
index 47d15c8f83ad0a3a55948f13613d4afd92fe57c3..606569a0d09b12c2505c7aa70911098e2740094c 100644 (file)
@@ -95,4 +95,11 @@ Ignoring units will cause model scaling (as dimensions are supposed to be specif
         <translation>microinch</translation>
     </message>
 </context>
+<context>
+    <name>STEPPlugin_ImportDlg</name>
+    <message>
+        <source>STEP_CREATE_ASSEMBLIES</source>
+        <translation>Create assemblies</translation>
+    </message>
+</context>
 </TS>