From d8a06d416178e50d5fadfc40215a3c2909d33910 Mon Sep 17 00:00:00 2001 From: skv Date: Tue, 25 Feb 2014 16:21:09 +0400 Subject: [PATCH] 0022468: [CEA 1048] IMP GEOM: creating groups on materials at STEP import --- doc/salome/gui/GEOM/input/import_export.doc | 4 + idl/GEOM_Gen.idl | 4 +- src/GEOMImpl/GEOMImpl_IInsertOperations.cxx | 210 +++++++++++- src/GEOMImpl/GEOMImpl_IInsertOperations.hxx | 18 +- src/GEOMToolsGUI/GEOMToolsGUI.cxx | 18 +- src/GEOM_I/GEOM_Gen_i.cc | 4 +- src/GEOM_I/GEOM_IInsertOperations_i.cc | 25 +- src/GEOM_I/GEOM_IInsertOperations_i.hh | 4 +- src/GEOM_I_Superv/GEOM_Superv_i.cc | 8 +- src/GEOM_SWIG/geomBuilder.py | 32 +- src/STEPImport/STEPImport.cxx | 341 +++++++++++++++----- 11 files changed, 551 insertions(+), 117 deletions(-) diff --git a/doc/salome/gui/GEOM/input/import_export.doc b/doc/salome/gui/GEOM/input/import_export.doc index ccc5c6a7e..50b792030 100644 --- a/doc/salome/gui/GEOM/input/import_export.doc +++ b/doc/salome/gui/GEOM/input/import_export.doc @@ -10,6 +10,10 @@ example, CATIA 5). The \subpage xao_format_page "import and export of shapes in XAO format" is implemented differently. +\note If a plugin supports import of materials associated with shapes, these +shapes are grouped corresponding to the imported materials. For the moment STEP +import is the only plugin that supports this feature. + To import geometrical objects from a BREP, IGES, STEP, ACIS or STL file: \par diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 62a3e36fb..630b66067 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -3682,9 +3682,9 @@ module GEOM * If format 'IGES_SCALE' is used instead of 'IGES' or * format 'STEP_SCALE' is used instead of 'STEP', * file length unit will be ignored (set to 'meter') and result model will be scaled. - * \return New GEOM_Object, containing the imported shape. + * \return List of GEOM_Object, containing the created shape and groups of materials. */ - GEOM_Object ImportFile (in string theFileName, in string theFormatName); + ListOfGO ImportFile (in string theFileName, in string theFormatName); /*! * \brief Read a value of parameter from a file, containing a shape. diff --git a/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx b/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx index d1c694af4..561e92fd0 100644 --- a/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IInsertOperations.cxx @@ -64,8 +64,13 @@ #include #include #include +#include #include #include +#include +#include +#include +#include #include #include @@ -238,7 +243,7 @@ void GEOMImpl_IInsertOperations::Export * Import */ //============================================================================= -Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IInsertOperations::Import (const TCollection_AsciiString& theFileName, const TCollection_AsciiString& theFormatName) { @@ -247,19 +252,21 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import if (theFileName.IsEmpty() || theFormatName.IsEmpty()) return NULL; //Add a new result object - Handle(GEOM_Object) result = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT); + Handle(GEOM_Object) anImported = GetEngine()->AddObject(GetDocID(), GEOM_IMPORT); //Add an Import function - Handle(GEOM_Function) aFunction = result->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE); - if (aFunction.IsNull()) return result; + Handle(GEOM_Function) aFunction = + anImported->AddFunction(GEOMImpl_ImportDriver::GetID(), IMPORT_SHAPE); + + if (aFunction.IsNull()) return NULL; //Check if the function is set correctly - if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return result; + if (aFunction->GetDriverGUID() != GEOMImpl_ImportDriver::GetID()) return NULL; Handle(TCollection_HAsciiString) aHLibName; if (!IsSupported (Standard_True, GetImportFormatName(theFormatName), aHLibName)) { - return result; + return NULL; } TCollection_AsciiString aLibName = aHLibName->String(); @@ -270,6 +277,8 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import aCI.SetPluginName(aLibName); //Perform the Import + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + try { #if OCC_VERSION_LARGE > 0x06010000 OCC_CATCH_SIGNALS; @@ -278,6 +287,11 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import SetErrorCode("Import driver failed"); return NULL; } + + aSeq->Append(anImported); + + // Greate material groups. + MakeMaterialGroups(anImported, aSeq); } catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); @@ -289,17 +303,17 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import if (theFormatName != "IGES_UNIT") { GEOM::TPythonDump pd (aFunction); if (theFormatName == "BREP") - pd << result << " = geompy.ImportBREP(\"" << theFileName.ToCString() << "\")"; + pd << anImported << " = geompy.ImportBREP(\"" << theFileName.ToCString() << "\")"; else if (theFormatName == "IGES") - pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\")"; + pd << anImported << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\")"; else if (theFormatName == "IGES_SCALE") - pd << result << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\", True)"; + pd << anImported << " = geompy.ImportIGES(\"" << theFileName.ToCString() << "\", True)"; else if (theFormatName == "STEP") - pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")"; + pd << anImported << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\")"; else if (theFormatName == "STEP_SCALE") - pd << result << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)"; + pd << anImported << " = geompy.ImportSTEP(\"" << theFileName.ToCString() << "\", True)"; else { - pd << result << " = geompy.ImportFile(\"" + pd << anImported << " = geompy.ImportFile(\"" << theFileName.ToCString() << "\", \"" << theFormatName.ToCString() << "\")"; } } @@ -322,7 +336,7 @@ Handle(GEOM_Object) GEOMImpl_IInsertOperations::Import } // OLD CODE: end - return result; + return aSeq; } //============================================================================= @@ -1394,3 +1408,173 @@ bool GEOMImpl_IInsertOperations::ImportXAO(const char* fileName, return true; } + +//============================================================================= +/*! + * This method creates material groups for an imported object. + * \param theObject the imported object. + */ +//============================================================================= +void GEOMImpl_IInsertOperations::MakeMaterialGroups + (const Handle(GEOM_Object) &theObject, + const Handle(TColStd_HSequenceOfTransient) &theSeq) +{ + TopoDS_Shape aResShape = theObject->GetValue(); + + if (aResShape.IsNull() == Standard_False) { + // Group shapes by material names. + Handle(GEOM_Function) aFunction = theObject->GetLastFunction(); + DataMapOfStringListOfShape aMapMaterialShapes; + + // check all named shapes using iterator + TDF_ChildIDIterator anIt (aFunction->GetNamingEntry(), + TNaming_NamedShape::GetID(), Standard_True); + + for (; anIt.More(); anIt.Next()) { + Handle(TNaming_NamedShape) anAttr = + Handle(TNaming_NamedShape)::DownCast(anIt.Value()); + + if (anAttr.IsNull() == Standard_False) { + TDF_Label aLabel = anAttr->Label(); + Handle(TDataStd_Comment) aComment; + + if (aLabel.FindAttribute(TDataStd_Comment::GetID(), aComment)) { + TCollection_ExtendedString aMatName = aComment->Get(); + TopoDS_Shape aShape = anAttr->Get(); + + if (aMapMaterialShapes.IsBound(aMatName) == Standard_False) { + NCollection_List anEmptyList; + + aMapMaterialShapes.Bind(aMatName, anEmptyList); + } + + aMapMaterialShapes(aMatName).Append(aShape); + } + } + } + + if (aMapMaterialShapes.IsEmpty() == Standard_False) { + // Construct groups. + TopAbs_ShapeEnum aType = aResShape.ShapeType(); + Standard_Integer i; + DataMapOfStringListOfShape::Iterator aMapIter; + + // Check each shape type. + for(i = aType; i <= TopAbs_VERTEX; i++) { + DataMapOfStringListOfShape::Iterator aMapIter(aMapMaterialShapes); + + for (; aMapIter.More(); aMapIter.Next()) { + NCollection_List &aShList = aMapIter.ChangeValue(); + NCollection_List::Iterator aShIter(aShList); + NCollection_List aShListSameType; + + while (aShIter.More()) { + const TopoDS_Shape &aShape = aShIter.Value(); + + if (i == aShape.ShapeType()) { + // Treat this element. + aShListSameType.Append(aShape); + aShList.Remove(aShIter); + } else { + // Go to the next element. + aShIter.Next(); + } + } + + if (aShListSameType.IsEmpty() == Standard_False) { + // Construct a group. + Handle(GEOM_Object) aGroup = + MakeGroup(theObject, aMapIter.Key(), aShListSameType); + + if (aGroup.IsNull() == Standard_False) { + theSeq->Append(aGroup); + } + } + } + } + } + } +} + + +//============================================================================= +/*! + * This method creates a group of shapes of certain type. + * \param theObject the imported object. + * \param theName the material name. + * \param theShapes the list of shapes to be added to this group. + * \return the created group. + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IInsertOperations::MakeGroup + (const Handle(GEOM_Object) &theObject, + const TCollection_ExtendedString &theName, + const NCollection_List &theShapes) +{ + Handle(GEOM_Object) aGroup; + TopTools_IndexedMapOfShape anIndices; + Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger; + NCollection_List::Iterator anIter(theShapes); + + TopExp::MapShapes(theObject->GetValue(), anIndices); + + // Compose shape IDs. + for (; anIter.More(); anIter.Next()) { + const TopoDS_Shape &aShape = anIter.Value(); + const Standard_Integer anIndex = anIndices.FindIndex(aShape); + + if (anIndex > 0) { + aSeqIDs->Append(anIndex); + } + } + + if (aSeqIDs->IsEmpty() == Standard_False) { + // Create a group. + const TopAbs_ShapeEnum aType = theShapes.First().ShapeType(); + + aGroup = myGroupOperations->CreateGroup(theObject, aType); + + if (aGroup.IsNull() == Standard_False) { + aGroup->GetLastFunction()->SetDescription(""); + myGroupOperations->UnionIDs(aGroup, aSeqIDs); + aGroup->GetLastFunction()->SetDescription(""); + + // Compose the group name. + TCollection_AsciiString aGroupName(theName); + + switch(aType) { + case TopAbs_VERTEX: + aGroupName += "_VERTEX"; + break; + case TopAbs_EDGE: + aGroupName += "_EDGE"; + break; + case TopAbs_WIRE: + aGroupName += "_WIRE"; + break; + case TopAbs_FACE: + aGroupName += "_FACE"; + break; + case TopAbs_SHELL: + aGroupName += "_SHELL"; + break; + case TopAbs_SOLID: + aGroupName += "_SOLID"; + break; + case TopAbs_COMPSOLID: + aGroupName += "_COMPSOLID"; + break; + case TopAbs_COMPOUND: + aGroupName += "_COMPOUND"; + break; + default: + aGroupName += "_SHAPE"; + break; + } + + aGroup->SetName(aGroupName.ToCString()); + } + } + + return aGroup; +} diff --git a/src/GEOMImpl/GEOMImpl_IInsertOperations.hxx b/src/GEOMImpl/GEOMImpl_IInsertOperations.hxx index ab574e0b3..0aa30a519 100644 --- a/src/GEOMImpl/GEOMImpl_IInsertOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IInsertOperations.hxx @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include @@ -55,6 +57,9 @@ namespace XAO { class Xao; } +typedef NCollection_DataMap > + DataMapOfStringListOfShape; + class GEOMImpl_IInsertOperations : public GEOM_IOperations { public: Standard_EXPORT GEOMImpl_IInsertOperations(GEOM_Engine* theEngine, int theDocID); @@ -63,8 +68,9 @@ class GEOMImpl_IInsertOperations : public GEOM_IOperations { Standard_EXPORT Handle(GEOM_Object) MakeCopy (Handle(GEOM_Object) theOriginal); - Standard_EXPORT Handle(GEOM_Object) Import (const TCollection_AsciiString& theFileName, - const TCollection_AsciiString& theFormatType); + Standard_EXPORT Handle(TColStd_HSequenceOfTransient) Import + (const TCollection_AsciiString& theFileName, + const TCollection_AsciiString& theFormatType); Standard_EXPORT TCollection_AsciiString ReadValue (const TCollection_AsciiString& theFileName, const TCollection_AsciiString& theFormatType, @@ -128,6 +134,14 @@ class GEOMImpl_IInsertOperations : public GEOM_IOperations { void exportGroups(std::list groupList, XAO::Xao* xaoObject, XAO::BrepGeometry* geometry); + void MakeMaterialGroups(const Handle(GEOM_Object) &theObject, + const Handle(TColStd_HSequenceOfTransient) &theSeq); + + Handle(GEOM_Object) MakeGroup + (const Handle(GEOM_Object) &theObject, + const TCollection_ExtendedString &theName, + const NCollection_List &theShapes); + private: Handle(Resource_Manager) myResMgr; Handle(Resource_Manager) myResMgrUser; diff --git a/src/GEOMToolsGUI/GEOMToolsGUI.cxx b/src/GEOMToolsGUI/GEOMToolsGUI.cxx index c02b6d688..daf888e2d 100644 --- a/src/GEOMToolsGUI/GEOMToolsGUI.cxx +++ b/src/GEOMToolsGUI/GEOMToolsGUI.cxx @@ -818,9 +818,10 @@ bool GEOMToolsGUI::Import() } // else if ( aCurrentType == "ACIS" ) // IMPORT - GEOM::GEOM_Object_var anObj = aInsOp->ImportFile( fileN, fileT ); + GEOM::ListOfGO_var anObj = aInsOp->ImportFile( fileN, fileT ); - if ( !anObj->_is_nil() && aInsOp->IsDone() ) { + if ( anObj->length() > 0 && aInsOp->IsDone() ) { + GEOM::GEOM_Object_ptr aFather = anObj[0]._retn(); QString aPublishObjName = GEOMBase::GetDefaultName( SUIT_Tools::file( fileName, /*withExten=*/true ) ); @@ -828,19 +829,26 @@ bool GEOMToolsGUI::Import() SALOMEDS::SObject_var aSO = GeometryGUI::GetGeomGen()->PublishInStudy( aDSStudy, SALOMEDS::SObject::_nil(), - anObj, + aFather, aPublishObjName.toLatin1().constData() ); if ( ( !aSO->_is_nil() ) ) anEntryList.append( aSO->GetID() ); - objsForDisplay.append( anObj ); + objsForDisplay.append( aFather ); if ( aCurrentType == "ACIS" ) { if ( acisAnswer == SUIT_MessageBox::Yes || acisAnswer == SUIT_MessageBox::YesToAll ) - GeometryGUI::GetGeomGen()->PublishNamedShapesInStudy( aDSStudy, anObj ); + GeometryGUI::GetGeomGen()->PublishNamedShapesInStudy( aDSStudy, aFather ); } anOp->commit(); + + // Treat group objects. + for (int i = 1, n = anObj->length(); i < n; i++) { + GEOM::GEOM_Object_ptr anObject = anObj[i]._retn(); + GeometryGUI::GetGeomGen()->AddInStudy(aDSStudy, + anObject, tr(anObject->GetName()).toStdString().c_str(), aFather); + } } else { anOp->abort(); diff --git a/src/GEOM_I/GEOM_Gen_i.cc b/src/GEOM_I/GEOM_Gen_i.cc index 38c0065c0..5a9685b5d 100644 --- a/src/GEOM_I/GEOM_Gen_i.cc +++ b/src/GEOM_I/GEOM_Gen_i.cc @@ -243,9 +243,10 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, aResultSO->SetAttrString("AttributeIOR",aGeomObjIOR); TCollection_AsciiString anObjectName, aNamePrefix("Shape_"); + CORBA::Long mytype=aBaseObj->GetType(); // BEGIN: try to find existed name for current shape - if ( !aShape->_is_nil() ) + if ( !aShape->_is_nil() && mytype != GEOM_GROUP) { // recieve current TopoDS shape CORBA::String_var entry = aShape->GetEntry(); @@ -279,7 +280,6 @@ SALOMEDS::SObject_ptr GEOM_Gen_i::PublishInStudy(SALOMEDS::Study_ptr theStudy, } // END: try to find existed name for current shape - CORBA::Long mytype=aBaseObj->GetType(); if ( mytype == GEOM_GROUP ) { GEOM::GEOM_IGroupOperations_var anOp = GetIGroupOperations( theStudy->StudyId() ); switch ( (TopAbs_ShapeEnum)anOp->GetType( aShape )) { diff --git a/src/GEOM_I/GEOM_IInsertOperations_i.cc b/src/GEOM_I/GEOM_IInsertOperations_i.cc index 50eadf77b..3d8f79751 100644 --- a/src/GEOM_I/GEOM_IInsertOperations_i.cc +++ b/src/GEOM_I/GEOM_IInsertOperations_i.cc @@ -125,11 +125,11 @@ void GEOM_IInsertOperations_i::Export * ImportFile */ //============================================================================= -GEOM::GEOM_Object_ptr GEOM_IInsertOperations_i::ImportFile +GEOM::ListOfGO* GEOM_IInsertOperations_i::ImportFile (const char* theFileName, const char* theFormatName) { - GEOM::GEOM_Object_var aGEOMObject; + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; //Set a not done flag GetOperations()->SetNotDone(); @@ -137,22 +137,31 @@ GEOM::GEOM_Object_ptr GEOM_IInsertOperations_i::ImportFile //Import the shape from the file char* aFileName = strdup(theFileName); char* aFormatName = strdup(theFormatName); - Handle(GEOM_Object) anObject = GetOperations()->Import(aFileName, aFormatName); + Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->Import(aFileName, aFormatName); - if( strcmp(aFormatName,"IGES_UNIT")==0 && !anObject.IsNull() ) { + if( strcmp(aFormatName,"IGES_UNIT")==0 && !aHSeq.IsNull() ) { free(aFileName); free(aFormatName); - return GetObject(anObject); + return aSeq._retn(); } free(aFileName); free(aFormatName); - if (!GetOperations()->IsDone() || anObject.IsNull()) { - return aGEOMObject._retn(); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) { + return aSeq._retn(); } - return GetObject(anObject); + // Copy created objects. + Standard_Integer aLength = aHSeq->Length(); + + aSeq->length(aLength); + + for (Standard_Integer i = 1; i <= aLength; i++) { + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + } + + return aSeq._retn(); } //============================================================================= diff --git a/src/GEOM_I/GEOM_IInsertOperations_i.hh b/src/GEOM_I/GEOM_IInsertOperations_i.hh index c9088371e..d36e0446d 100644 --- a/src/GEOM_I/GEOM_IInsertOperations_i.hh +++ b/src/GEOM_I/GEOM_IInsertOperations_i.hh @@ -49,8 +49,8 @@ class GEOM_I_EXPORT GEOM_IInsertOperations_i : const char* theFileName, const char* theFormatName); - GEOM::GEOM_Object_ptr ImportFile (const char* theFileName, - const char* theFormatName); + GEOM::ListOfGO* ImportFile (const char* theFileName, + const char* theFormatName); char* ReadValue (const char* theFileName, const char* theFormatName, diff --git a/src/GEOM_I_Superv/GEOM_Superv_i.cc b/src/GEOM_I_Superv/GEOM_Superv_i.cc index 9e999020c..708f793dc 100644 --- a/src/GEOM_I_Superv/GEOM_Superv_i.cc +++ b/src/GEOM_I_Superv/GEOM_Superv_i.cc @@ -1588,7 +1588,13 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::ImportFile (const char* theFileName, beginService( " GEOM_Superv_i::ImportFile" ); MESSAGE("GEOM_Superv_i::ImportFile"); getInsOp(); - GEOM::GEOM_Object_ptr anObj = myInsOp->ImportFile(theFileName, theFormatName); + GEOM::ListOfGO* aSeq = myInsOp->ImportFile(theFileName, theFormatName); + GEOM::GEOM_Object_ptr anObj; + + if (aSeq->length() > 0) { + anObj = aSeq->operator[](0); + } + endService( " GEOM_Superv_i::ImportFile" ); return anObj; } diff --git a/src/GEOM_SWIG/geomBuilder.py b/src/GEOM_SWIG/geomBuilder.py index 2507e2c2c..9b1a12a27 100644 --- a/src/GEOM_SWIG/geomBuilder.py +++ b/src/GEOM_SWIG/geomBuilder.py @@ -10303,6 +10303,11 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # publication is switched on, default value is used for result name. # # @return New GEOM.GEOM_Object, containing the imported shape. + # If material names are imported it returns the list of + # objects. The first one is the imported object followed by + # material groups. + # @note Auto publishing is allowed for the shape itself. Imported + # material groups are not automatically published. # # @ref swig_Import_Export "Example" def ImportFile(self, theFileName, theFormatName, theName=None): @@ -10323,12 +10328,22 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): Returns: New GEOM.GEOM_Object, containing the imported shape. + If material names are imported it returns the list of + objects. The first one is the imported object followed by + material groups. + Note: + Auto publishing is allowed for the shape itself. Imported + material groups are not automatically published. """ # Example: see GEOM_TestOthers.py - anObj = self.InsertOp.ImportFile(theFileName, theFormatName) + aListObj = self.InsertOp.ImportFile(theFileName, theFormatName) RaiseIfFailed("ImportFile", self.InsertOp) - self._autoPublish(anObj, theName, "imported") - return anObj + aNbObj = len(aListObj) + if aNbObj > 0: + self._autoPublish(aListObj[0], theName, "imported") + if aNbObj == 1: + return aListObj[0] + return aListObj ## Deprecated analog of ImportFile() def Import(self, theFileName, theFormatName, theName=None): @@ -10432,6 +10447,11 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): # publication is switched on, default value is used for result name. # # @return New GEOM.GEOM_Object, containing the imported shape. + # If material names are imported it returns the list of + # objects. The first one is the imported object followed by + # material groups. + # @note Auto publishing is allowed for the shape itself. Imported + # material groups are not automatically published. # # @ref swig_Import_Export "Example" def ImportSTEP(self, theFileName, ignoreUnits = False, theName=None): @@ -10449,6 +10469,12 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen): Returns: New GEOM.GEOM_Object, containing the imported shape. + If material names are imported it returns the list of + objects. The first one is the imported object followed by + material groups. + Note: + Auto publishing is allowed for the shape itself. Imported + material groups are not automatically published. """ # Example: see GEOM_TestOthers.py # note: auto-publishing is done in self.ImportFile() diff --git a/src/STEPImport/STEPImport.cxx b/src/STEPImport/STEPImport.cxx index 0dd1bcfd0..0dc8d7057 100644 --- a/src/STEPImport/STEPImport.cxx +++ b/src/STEPImport/STEPImport.cxx @@ -32,10 +32,13 @@ #include #include #include +#include #include #include #include +#include +#include #include #include #include @@ -44,6 +47,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -75,6 +82,254 @@ #define STEPIMPORT_EXPORT #endif + +//============================================================================= +/*! + * GetShape() + */ +//============================================================================= + +static TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti, + const Handle(Transfer_TransientProcess) &theTP) +{ + TopoDS_Shape aResult; + Handle(Transfer_Binder) aBinder = theTP->Find(theEnti); + + if (aBinder.IsNull()) { + return aResult; + } + + aResult = TransferBRep::ShapeResult(aBinder); + + return aResult; +} + +//============================================================================= +/*! + * GetLabel() + */ +//============================================================================= + +static TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti, + const TDF_Label &theShapeLabel, + const TopoDS_Shape &aShape) +{ + TDF_Label aResult; + + if (theEnti->IsKind + (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) { + // check all named shapes using iterator + TDF_ChildIDIterator anIt + (theShapeLabel, TDataStd_Name::GetID(), Standard_True); + + for (; anIt.More(); anIt.Next()) { + Handle(TDataStd_Name) nameAttr = + Handle(TDataStd_Name)::DownCast(anIt.Value()); + + if (nameAttr.IsNull()) { + continue; + } + + TDF_Label aLab = nameAttr->Label(); + Handle(TNaming_NamedShape) shAttr; + + if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) && + shAttr->Get().IsEqual(aShape)) { + aResult = aLab; + } + } + } + + // create label and set shape + if (aResult.IsNull()) { + TDF_TagSource aTag; + + aResult = aTag.NewChild(theShapeLabel); + + TNaming_Builder tnBuild (aResult); + + tnBuild.Generated(aShape); + } + + return aResult; +} + +//============================================================================= +/*! + * StoreName() + */ +//============================================================================= + +static void StoreName(const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel) +{ + 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 { + Handle(StepBasic_ProductDefinition) PD = + Handle(StepBasic_ProductDefinition)::DownCast(theEnti); + + if (PD.IsNull() == Standard_False) { + Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct(); + aName = Prod->Name(); + } + } + + bool isValidName = false; + + if (aName.IsNull() == Standard_False) { + isValidName = true; + + if (aName->UsefullLength() < 1) { + isValidName = false; + } else if (aName->UsefullLength() == 4 && + toupper (aName->Value(1)) == 'N' && + toupper (aName->Value(2)) == 'O' && + toupper (aName->Value(3)) == 'N' && + toupper (aName->Value(4)) == 'E') { + // skip 'N0NE' name + isValidName = false; + } else { + // special check to pass names like "Open CASCADE STEP translator 6.3 1" + TCollection_AsciiString aSkipName ("Open CASCADE STEP translator"); + + if (aName->Length() >= aSkipName.Length()) { + if (aName->String().SubString + (1, aSkipName.Length()).IsEqual(aSkipName)) { + isValidName = false; + } + } + } + } + + if (isValidName) { + TCollection_ExtendedString aNameExt (aName->ToCString()); + + // find target shape + TopoDS_Shape S = GetShape(theEnti, theTP); + + if (S.IsNull()) { + return; + } + + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer isub, nbSubs = theIndices.Extent(); + + for (isub = 1; isub <= nbSubs; isub++) { + TopoDS_Shape aSub = theIndices.FindKey(isub); + + if (aSub.IsPartner(S)) { + TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub); + + // set a name + TDataStd_Name::Set(L, aNameExt); + } + } + } +} + +//============================================================================= +/*! + * StoreMaterial() + */ +//============================================================================= + +static void StoreMaterial + (const Handle(Standard_Transient) &theEnti, + const TopTools_IndexedMapOfShape &theIndices, + const Handle(Transfer_TransientProcess) &theTP, + const TDF_Label &theShapeLabel) +{ + // Treat Product Definition Shape only. + Handle(StepRepr_ProductDefinitionShape) aPDS = + Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti); + Handle(StepBasic_ProductDefinition) aProdDef; + + if(aPDS.IsNull() == Standard_False) { + // Product Definition Shape ==> Product Definition + aProdDef = aPDS->Definition().ProductDefinition(); + } + + if (aProdDef.IsNull() == Standard_False) { + // Product Definition ==> Property Definition + const Interface_Graph &aGraph = theTP->Graph(); + Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef); + TopoDS_Shape aShape; + + for(aSubs.Start(); aSubs.More(); aSubs.Next()) { + Handle(StepRepr_PropertyDefinition) aPropD = + Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value()); + + if(aPropD.IsNull() == Standard_False) { + // Property Definition ==> Representation. + Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD); + + for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) { + Handle(StepRepr_PropertyDefinitionRepresentation) aPDR = + Handle(StepRepr_PropertyDefinitionRepresentation):: + DownCast(aSubs1.Value()); + + if(aPDR.IsNull() == Standard_False) { + // Property Definition ==> Material Name. + Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation(); + + if(aRepr.IsNull() == Standard_False) { + Standard_Integer ir; + + for(ir = 1; ir <= aRepr->NbItems(); ir++) { + Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir); + Handle(StepRepr_DescriptiveRepresentationItem) aDRI = + Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI); + + if(aDRI.IsNull() == Standard_False) { + // Get shape from Product Definition + Handle(TCollection_HAsciiString) aMatName = aDRI->Name(); + + if(aMatName.IsNull() == Standard_False) { + TCollection_ExtendedString + aMatNameExt (aMatName->ToCString()); + + if (aShape.IsNull()) { + // Get the shape. + aShape = GetShape(aProdDef, theTP); + + if (aShape.IsNull()) { + return; + } + } + + // as PRODUCT can be included in the main shape + // several times, we look here for all iclusions. + Standard_Integer isub, nbSubs = theIndices.Extent(); + + for (isub = 1; isub <= nbSubs; isub++) { + TopoDS_Shape aSub = theIndices.FindKey(isub); + + if (aSub.IsPartner(aShape)) { + TDF_Label aLabel = + GetLabel(aProdDef, theShapeLabel, aSub); + + // set a name + TDataStd_Comment::Set(aLabel, aMatNameExt); + } + } + } + } + } + } + } + } + } + } + } +} + //============================================================================= /*! * Import() @@ -271,7 +526,7 @@ extern "C" return TopoDS_Shape(); } - // BEGIN: Store names of sub-shapes from file + // BEGIN: Store names and materials of sub-shapes from file TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aResShape, anIndices); @@ -279,92 +534,20 @@ extern "C" Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader(); if (!TR.IsNull()) { Handle(Transfer_TransientProcess) TP = TR->TransientProcess(); - Handle(Standard_Type) tPD = STANDARD_TYPE(StepBasic_ProductDefinition); - Handle(Standard_Type) tShape = STANDARD_TYPE(StepShape_TopologicalRepresentationItem); - Handle(Standard_Type) tGeom = STANDARD_TYPE(StepGeom_GeometricRepresentationItem); Standard_Integer nb = Model->NbEntities(); + for (Standard_Integer ie = 1; ie <= nb; ie++) { Handle(Standard_Transient) enti = Model->Value(ie); - Handle(TCollection_HAsciiString) aName; - if ( enti->IsKind( tShape ) || enti->IsKind(tGeom)) - { - aName = Handle(StepRepr_RepresentationItem)::DownCast(enti)->Name(); - } - else if (enti->DynamicType() == tPD) - { - Handle(StepBasic_ProductDefinition) PD = - Handle(StepBasic_ProductDefinition)::DownCast(enti); - if (PD.IsNull()) continue; - Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct(); - aName = Prod->Name(); - } - else - { - continue; - } - if ( aName->UsefullLength() < 1 ) - continue; - // skip 'N0NE' name - if ( aName->UsefullLength() == 4 && - toupper (aName->Value(1)) == 'N' && - toupper (aName->Value(2)) == 'O' && - toupper (aName->Value(3)) == 'N' && - toupper (aName->Value(4)) == 'E') - continue; + // Store names. + StoreName(enti, anIndices, TP, theShapeLabel); - // special check to pass names like "Open CASCADE STEP translator 6.3 1" - TCollection_AsciiString aSkipName ("Open CASCADE STEP translator"); - if (aName->Length() >= aSkipName.Length()) { - if (aName->String().SubString(1, aSkipName.Length()).IsEqual(aSkipName)) - continue; - } - TCollection_ExtendedString aNameExt (aName->ToCString()); - - // find target shape - Handle(Transfer_Binder) binder = TP->Find(enti); - if (binder.IsNull()) continue; - TopoDS_Shape S = TransferBRep::ShapeResult(binder); - if (S.IsNull()) continue; - - // as PRODUCT can be included in the main shape - // several times, we look here for all iclusions. - Standard_Integer isub, nbSubs = anIndices.Extent(); - for (isub = 1; isub <= nbSubs; isub++) - { - TopoDS_Shape aSub = anIndices.FindKey(isub); - if (aSub.IsPartner(S)) { - TDF_Label L; - if (enti->IsKind(tGeom)) { - // check all named shapes using iterator - TDF_ChildIDIterator anIt (theShapeLabel, TDataStd_Name::GetID(), Standard_True); - for (; anIt.More(); anIt.Next()) { - Handle(TDataStd_Name) nameAttr = - Handle(TDataStd_Name)::DownCast(anIt.Value()); - if (nameAttr.IsNull()) continue; - TDF_Label Lab = nameAttr->Label(); - Handle(TNaming_NamedShape) shAttr; - if (Lab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) && shAttr->Get().IsEqual(aSub)) - L = Lab; - } - } - // create label and set shape - if (L.IsNull()) - { - TDF_TagSource aTag; - L = aTag.NewChild(theShapeLabel); - TNaming_Builder tnBuild (L); - //tnBuild.Generated(S); - tnBuild.Generated(aSub); - } - // set a name - TDataStd_Name::Set(L, aNameExt); - } - } + // Store materials. + StoreMaterial(enti, anIndices, TP, theShapeLabel); } } - // END: Store names + // END: Store names and materials } else { // switch (status) {