1 // Copyright (C) 2014-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include "STEPPlugin_ImportDriver.hxx"
22 #include "STEPPlugin_IImport.hxx"
25 #include <utilities.h>
26 #include <Basics_Utils.hxx>
29 #include "GEOM_Function.hxx"
30 #include "GEOMImpl_Types.hxx"
33 #include <TDF_ChildIDIterator.hxx>
34 #include <TDF_Label.hxx>
35 #include <TDataStd_Name.hxx>
36 #include <TDataStd_Comment.hxx>
37 #include <TNaming_Builder.hxx>
38 #include <TNaming_NamedShape.hxx>
39 #include <Interface_EntityIterator.hxx>
40 #include <Interface_Graph.hxx>
41 #include <Interface_InterfaceModel.hxx>
42 #include <Interface_Static.hxx>
43 #include <STEPControl_Reader.hxx>
44 #include <StepBasic_Product.hxx>
45 #include <StepBasic_ProductDefinition.hxx>
46 #include <StepBasic_ProductDefinitionFormation.hxx>
47 #include <StepGeom_GeometricRepresentationItem.hxx>
48 #include <StepShape_TopologicalRepresentationItem.hxx>
49 #include <StepRepr_DescriptiveRepresentationItem.hxx>
50 #include <StepRepr_ProductDefinitionShape.hxx>
51 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
52 #include <StepRepr_Representation.hxx>
53 #include <TransferBRep.hxx>
54 #include <Transfer_TransientProcess.hxx>
55 #include <XSControl_TransferReader.hxx>
56 #include <XSControl_WorkSession.hxx>
57 #include <BRep_Builder.hxx>
59 #include <TopExp_Explorer.hxx>
60 #include <TopTools_IndexedMapOfShape.hxx>
61 #include <TopoDS_Compound.hxx>
62 #include <TopoDS_Iterator.hxx>
63 #include <TColStd_SequenceOfAsciiString.hxx>
65 #include <StdFail_NotDone.hxx>
66 #include <Standard_Failure.hxx>
67 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
71 //=============================================================================
75 //=============================================================================
77 TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti,
78 const Handle(Transfer_TransientProcess) &theTP)
81 Handle(Transfer_Binder) aBinder = theTP->Find(theEnti);
83 if (aBinder.IsNull()) {
87 aResult = TransferBRep::ShapeResult(aBinder);
92 //=============================================================================
96 //=============================================================================
98 TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti,
99 const TDF_Label &theShapeLabel,
100 const TopoDS_Shape &aShape)
105 (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
106 // check all named shapes using iterator
107 TDF_ChildIDIterator anIt
108 (theShapeLabel, TDataStd_Name::GetID(), Standard_True);
110 for (; anIt.More(); anIt.Next()) {
111 Handle(TDataStd_Name) nameAttr =
112 Handle(TDataStd_Name)::DownCast(anIt.Value());
114 if (nameAttr.IsNull()) {
118 TDF_Label aLab = nameAttr->Label();
119 Handle(TNaming_NamedShape) shAttr;
121 if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) &&
122 shAttr->Get().IsEqual(aShape)) {
128 // create label and set shape
129 if (aResult.IsNull()) {
132 aResult = aTag.NewChild(theShapeLabel);
134 TNaming_Builder tnBuild (aResult);
136 tnBuild.Generated(aShape);
142 //=============================================================================
146 //=============================================================================
148 void StoreName( const Handle(Standard_Transient) &theEnti,
149 const TopTools_IndexedMapOfShape &theIndices,
150 const Handle(Transfer_TransientProcess) &theTP,
151 const TDF_Label &theShapeLabel)
153 Handle(TCollection_HAsciiString) aName;
155 if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) ||
156 theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
157 aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name();
159 Handle(StepBasic_ProductDefinition) PD =
160 Handle(StepBasic_ProductDefinition)::DownCast(theEnti);
162 if (PD.IsNull() == Standard_False) {
163 Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct();
164 aName = Prod->Name();
168 bool isValidName = false;
170 if (aName.IsNull() == Standard_False) {
173 if (aName->UsefullLength() < 1) {
175 } else if (aName->UsefullLength() == 4 &&
176 toupper (aName->Value(1)) == 'N' &&
177 toupper (aName->Value(2)) == 'O' &&
178 toupper (aName->Value(3)) == 'N' &&
179 toupper (aName->Value(4)) == 'E') {
183 // special check to pass names like "Open CASCADE STEP translator 6.3 1"
184 TCollection_AsciiString aSkipName ("Open CASCADE STEP translator");
186 if (aName->Length() >= aSkipName.Length()) {
187 if (aName->String().SubString
188 (1, aSkipName.Length()).IsEqual(aSkipName)) {
196 TCollection_ExtendedString aNameExt (aName->ToCString());
199 TopoDS_Shape S = GetShape(theEnti, theTP);
205 // as PRODUCT can be included in the main shape
206 // several times, we look here for all iclusions.
207 Standard_Integer isub, nbSubs = theIndices.Extent();
209 for (isub = 1; isub <= nbSubs; isub++) {
210 TopoDS_Shape aSub = theIndices.FindKey(isub);
212 if (aSub.IsPartner(S)) {
213 TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub);
216 TDataStd_Name::Set(L, aNameExt);
222 //=============================================================================
226 //=============================================================================
228 void StoreMaterial( const Handle(Standard_Transient) &theEnti,
229 const TopTools_IndexedMapOfShape &theIndices,
230 const Handle(Transfer_TransientProcess) &theTP,
231 const TDF_Label &theShapeLabel )
233 // Treat Product Definition Shape only.
234 Handle(StepRepr_ProductDefinitionShape) aPDS =
235 Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti);
236 Handle(StepBasic_ProductDefinition) aProdDef;
238 if(aPDS.IsNull() == Standard_False) {
239 // Product Definition Shape ==> Product Definition
240 aProdDef = aPDS->Definition().ProductDefinition();
243 if (aProdDef.IsNull() == Standard_False) {
244 // Product Definition ==> Property Definition
245 const Interface_Graph &aGraph = theTP->Graph();
246 Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef);
249 for(aSubs.Start(); aSubs.More(); aSubs.Next()) {
250 Handle(StepRepr_PropertyDefinition) aPropD =
251 Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value());
253 if(aPropD.IsNull() == Standard_False) {
254 // Property Definition ==> Representation.
255 Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD);
257 for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) {
258 Handle(StepRepr_PropertyDefinitionRepresentation) aPDR =
259 Handle(StepRepr_PropertyDefinitionRepresentation)::
260 DownCast(aSubs1.Value());
262 if(aPDR.IsNull() == Standard_False) {
263 // Property Definition ==> Material Name.
264 Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation();
266 if(aRepr.IsNull() == Standard_False) {
269 for(ir = 1; ir <= aRepr->NbItems(); ir++) {
270 Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir);
271 Handle(StepRepr_DescriptiveRepresentationItem) aDRI =
272 Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI);
274 if(aDRI.IsNull() == Standard_False) {
275 // Get shape from Product Definition
276 Handle(TCollection_HAsciiString) aMatName = aDRI->Name();
278 if(aMatName.IsNull() == Standard_False) {
279 TCollection_ExtendedString
280 aMatNameExt (aMatName->ToCString());
282 if (aShape.IsNull()) {
284 aShape = GetShape(aProdDef, theTP);
286 if (aShape.IsNull()) {
291 // as PRODUCT can be included in the main shape
292 // several times, we look here for all iclusions.
293 Standard_Integer isub, nbSubs = theIndices.Extent();
295 for (isub = 1; isub <= nbSubs; isub++) {
296 TopoDS_Shape aSub = theIndices.FindKey(isub);
298 if (aSub.IsPartner(aShape)) {
300 GetLabel(aProdDef, theShapeLabel, aSub);
303 TDataStd_Comment::Set(aLabel, aMatNameExt);
317 TCollection_AsciiString ToNamedUnit( const TCollection_AsciiString& unit )
319 TCollection_AsciiString result = unit;
321 if ( result == "mil" ) result = "milliinch";
325 TCollection_AsciiString ToOcctUnit( const TCollection_AsciiString& unit, TCollection_AsciiString& error )
327 TCollection_AsciiString result = "M", u = ToNamedUnit(unit);
332 else if (u == "milliinch")
334 else if (u == "microinch")
336 else if (u == "foot")
338 else if (u == "mile")
340 else if (u == "metre")
342 else if (u == "kilometre")
344 else if (u == "millimetre")
346 else if (u == "centimetre")
348 else if (u == "micrometre")
350 else if (u.IsEmpty())
353 error = "The file contains not supported units";
355 // TODO (for other units)
362 } // end of namespace
364 //=======================================================================
367 //=======================================================================
368 const Standard_GUID& STEPPlugin_ImportDriver::GetID()
370 static Standard_GUID aGUID("a25f88df-461b-45c0-ab6b-a82101fe6ce7");
374 //=======================================================================
375 //function : STEPPlugin_ImportDriver
377 //=======================================================================
378 STEPPlugin_ImportDriver::STEPPlugin_ImportDriver()
382 //=======================================================================
385 //=======================================================================
386 Standard_Integer STEPPlugin_ImportDriver::Execute( TFunction_Logbook& log ) const
388 if( Label().IsNull() ) return 0;
389 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction( Label() );
391 STEPPlugin_IImport aData( aFunction );
393 TCollection_AsciiString aFileName = aData.GetFileName().ToCString();
394 bool anIsIgnoreUnits = aData.GetIsIgnoreUnits();
395 TDF_Label aShapeLabel = aFunction->GetNamingEntry();
397 MESSAGE("Import STEP from file " << aFileName.ToCString() );
399 TopoDS_Shape aResShape;
400 TCollection_AsciiString anError;
402 // Set "C" numeric locale to save numbers correctly
403 Kernel_Utils::Localizer loc;
405 STEPControl_Reader aReader;
407 //VSR: 16/09/09: Convert to METERS
408 Interface_Static::SetCVal("xstep.cascade.unit","M");
409 Interface_Static::SetIVal("read.step.ideas", 1);
410 Interface_Static::SetIVal("read.step.nonmanifold", 1);
413 TopoDS_Compound compound;
414 B.MakeCompound(compound);
419 IFSelect_ReturnStatus status = aReader.ReadFile(aFileName.ToCString());
420 if (status == IFSelect_RetDone) {
421 // Regard or not the model units
422 if( anIsIgnoreUnits ) {
423 // set UnitFlag to units from file
424 TColStd_SequenceOfAsciiString anUnitLengthNames;
425 TColStd_SequenceOfAsciiString anUnitAngleNames;
426 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
427 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
428 if (anUnitLengthNames.Length() > 0) {
429 TCollection_AsciiString aLenUnits = ToOcctUnit(anUnitLengthNames.First(), anError);
430 Interface_Static::SetCVal("xstep.cascade.unit", aLenUnits.ToCString());
434 // Need re-scale a model (set UnitFlag to 'meter')
435 Interface_Static::SetCVal("xstep.cascade.unit","M");
438 Standard_Boolean failsonly = Standard_False;
439 aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
442 Standard_Integer nbr = aReader.NbRootsForTransfer();
443 aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
445 for (Standard_Integer n = 1; n <= nbr; n++) {
446 Standard_Boolean ok = aReader.TransferRoot(n);
447 // Collecting resulting entities
448 Standard_Integer nbs = aReader.NbShapes();
450 continue; // skip empty root
452 // For a single entity
453 else if (nbr == 1 && nbs == 1) {
454 aResShape = aReader.Shape(1);
455 if (aResShape.ShapeType() == TopAbs_COMPOUND) {
457 TopoDS_Shape currShape;
458 TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
459 for (; It.More(); It.Next()) {
461 currShape = It.Value();
464 aResShape = currShape;
469 for (Standard_Integer i = 1; i <= nbs; i++) {
470 TopoDS_Shape aShape = aReader.Shape(i);
474 B.Add(compound, aShape);
477 if( aResShape.IsNull() )
478 aResShape = compound;
480 // Check if any BRep entity has been read, there must be at least a vertex
481 if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
482 StdFail_NotDone::Raise( "No geometrical data in the imported file." );
484 // BEGIN: Store names and materials of sub-shapes from file
485 TopTools_IndexedMapOfShape anIndices;
486 TopExp::MapShapes(aResShape, anIndices);
488 Handle(Interface_InterfaceModel) Model = aReader.WS()->Model();
489 Handle(XSControl_TransferReader) TR = aReader.WS()->TransferReader();
491 Handle(Transfer_TransientProcess) TP = TR->TransientProcess();
493 Standard_Integer nb = Model->NbEntities();
495 for (Standard_Integer ie = 1; ie <= nb; ie++) {
496 Handle(Standard_Transient) enti = Model->Value(ie);
499 StoreName(enti, anIndices, TP, aShapeLabel);
502 StoreMaterial(enti, anIndices, TP, aShapeLabel);
505 // END: Store names and materials
509 case IFSelect_RetVoid:
510 anError = "Nothing created or No data to process";
512 case IFSelect_RetError:
513 anError = "Error in command or input data";
515 case IFSelect_RetFail:
516 anError = "Execution was run, but has failed";
518 case IFSelect_RetStop:
519 anError = "Execution has been stopped. Quite possible, an exception was raised";
524 anError = "Wrong format of the imported file. Can't import file.";
528 catch( Standard_Failure ) {
529 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
530 anError = aFail->GetMessageString();
534 if( aResShape.IsNull() ) {
535 StdFail_NotDone::Raise( anError.ToCString() );
539 aFunction->SetValue( aResShape );
541 log.SetTouched( Label() );
546 //=======================================================================
547 //function : MustExecute
549 //=======================================================================
550 Standard_Boolean STEPPlugin_ImportDriver::MustExecute( const TFunction_Logbook& ) const
552 return Standard_True;
555 //================================================================================
557 * \brief Returns a name of creation operation and names and values of creation parameters
559 //================================================================================
561 bool STEPPlugin_ImportDriver::
562 GetCreationInformation( std::string& theOperationName,
563 std::vector<GEOM_Param>& theParams )
565 if( Label().IsNull() ) return 0;
566 Handle(GEOM_Function) function = GEOM_Function::GetFunction( Label() );
568 STEPPlugin_IImport aCI( function );
569 Standard_Integer aType = function->GetType();
571 theOperationName = "ImportSTEP";
575 AddParam( theParams, "File name", aCI.GetFileName() );
576 if( aCI.GetIsIgnoreUnits() )
577 AddParam( theParams, "Format", "STEP_SCALE" );
585 TCollection_AsciiString
586 STEPPlugin_ImportDriver::GetValue( const TCollection_AsciiString& theFileName,
587 const TCollection_AsciiString& theParameterName,
588 TCollection_AsciiString& theError )
590 TCollection_AsciiString aValue;
592 if (theParameterName != "LEN_UNITS") {
593 theError = theParameterName + " parameter reading is not supported by STEP plugin";
594 return TCollection_AsciiString();
597 // Set "C" numeric locale to save numbers correctly
598 Kernel_Utils::Localizer loc;
600 STEPControl_Reader aReader;
602 Interface_Static::SetCVal( "xstep.cascade.unit","M" );
603 Interface_Static::SetIVal( "read.step.ideas", 1 );
604 Interface_Static::SetIVal( "read.step.nonmanifold", 1 );
608 IFSelect_ReturnStatus status = aReader.ReadFile( theFileName.ToCString() );
609 if (status == IFSelect_RetDone) {
610 TColStd_SequenceOfAsciiString anUnitLengthNames;
611 TColStd_SequenceOfAsciiString anUnitAngleNames;
612 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
613 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
614 if (anUnitLengthNames.Length() > 0)
615 aValue = ToNamedUnit( anUnitLengthNames.First() );
618 theError = theFileName + " reading failed";
621 catch( Standard_Failure ) {
622 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
623 theError = aFail->GetMessageString();
629 IMPLEMENT_STANDARD_HANDLE( STEPPlugin_ImportDriver, GEOM_BaseDriver );
630 IMPLEMENT_STANDARD_RTTIEXT( STEPPlugin_ImportDriver, GEOM_BaseDriver );