1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 #include <GeomAlgoAPI_STEPImport.h>
5 #include <TDF_ChildIDIterator.hxx>
6 #include <TDF_Label.hxx>
7 #include <TDataStd_Name.hxx>
8 #include <TDataStd_Comment.hxx>
9 #include <TNaming_Builder.hxx>
10 #include <TNaming_NamedShape.hxx>
12 #include <IFSelect_ReturnStatus.hxx>
13 #include <Interface_EntityIterator.hxx>
14 #include <Interface_Graph.hxx>
15 #include <Interface_InterfaceModel.hxx>
16 #include <Interface_Static.hxx>
17 #include <STEPControl_Reader.hxx>
18 #include <StepBasic_Product.hxx>
19 #include <StepBasic_ProductDefinition.hxx>
20 #include <StepBasic_ProductDefinitionFormation.hxx>
21 #include <StepGeom_GeometricRepresentationItem.hxx>
22 #include <StepShape_TopologicalRepresentationItem.hxx>
23 #include <StepRepr_DescriptiveRepresentationItem.hxx>
24 #include <StepRepr_ProductDefinitionShape.hxx>
25 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
26 #include <StepRepr_Representation.hxx>
27 #include <TransferBRep.hxx>
28 #include <Transfer_Binder.hxx>
29 #include <Transfer_TransientProcess.hxx>
30 #include <XSControl_TransferReader.hxx>
31 #include <XSControl_WorkSession.hxx>
33 #include <BRep_Builder.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TopoDS_Iterator.hxx>
41 #include <TColStd_SequenceOfAsciiString.hxx>
43 #include <Standard_Failure.hxx>
44 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
46 namespace STEPImport {
47 //=============================================================================
51 //=============================================================================
53 static TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti,
54 const Handle(Transfer_TransientProcess) &theTP)
57 Handle(Transfer_Binder) aBinder = theTP->Find(theEnti);
59 if (aBinder.IsNull()) {
63 aResult = TransferBRep::ShapeResult(aBinder);
68 //=============================================================================
72 //=============================================================================
74 static TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti,
75 const TDF_Label &theShapeLabel,
76 const TopoDS_Shape &aShape)
81 (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
82 // check all named shapes using iterator
83 TDF_ChildIDIterator anIt
84 (theShapeLabel, TDataStd_Name::GetID(), Standard_True);
86 for (; anIt.More(); anIt.Next()) {
87 Handle(TDataStd_Name) nameAttr =
88 Handle(TDataStd_Name)::DownCast(anIt.Value());
90 if (nameAttr.IsNull()) {
94 TDF_Label aLab = nameAttr->Label();
95 Handle(TNaming_NamedShape) shAttr;
97 if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) &&
98 shAttr->Get().IsEqual(aShape)) {
104 // create label and set shape
105 if (aResult.IsNull()) {
108 aResult = aTag.NewChild(theShapeLabel);
110 TNaming_Builder tnBuild (aResult);
112 tnBuild.Generated(aShape);
118 //=============================================================================
122 //=============================================================================
124 static void StoreName(const Handle(Standard_Transient) &theEnti,
125 const TopTools_IndexedMapOfShape &theIndices,
126 const Handle(Transfer_TransientProcess) &theTP,
127 const TDF_Label &theShapeLabel)
129 Handle(TCollection_HAsciiString) aName;
131 if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) ||
132 theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
133 aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name();
135 Handle(StepBasic_ProductDefinition) PD =
136 Handle(StepBasic_ProductDefinition)::DownCast(theEnti);
138 if (PD.IsNull() == Standard_False) {
139 Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct();
140 aName = Prod->Name();
144 bool isValidName = false;
146 if (aName.IsNull() == Standard_False) {
149 if (aName->UsefullLength() < 1) {
151 } else if (aName->UsefullLength() == 4 &&
152 toupper (aName->Value(1)) == 'N' &&
153 toupper (aName->Value(2)) == 'O' &&
154 toupper (aName->Value(3)) == 'N' &&
155 toupper (aName->Value(4)) == 'E') {
159 // special check to pass names like "Open CASCADE STEP translator 6.3 1"
160 TCollection_AsciiString aSkipName ("Open CASCADE STEP translator");
162 if (aName->Length() >= aSkipName.Length()) {
163 if (aName->String().SubString
164 (1, aSkipName.Length()).IsEqual(aSkipName)) {
172 TCollection_ExtendedString aNameExt (aName->ToCString());
175 TopoDS_Shape S = GetShape(theEnti, theTP);
181 // as PRODUCT can be included in the main shape
182 // several times, we look here for all iclusions.
183 Standard_Integer isub, nbSubs = theIndices.Extent();
185 for (isub = 1; isub <= nbSubs; isub++) {
186 TopoDS_Shape aSub = theIndices.FindKey(isub);
188 if (aSub.IsPartner(S)) {
189 TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub);
192 TDataStd_Name::Set(L, aNameExt);
198 //=============================================================================
202 //=============================================================================
204 static void StoreMaterial
205 (const Handle(Standard_Transient) &theEnti,
206 const TopTools_IndexedMapOfShape &theIndices,
207 const Handle(Transfer_TransientProcess) &theTP,
208 const TDF_Label &theShapeLabel)
210 // Treat Product Definition Shape only.
211 Handle(StepRepr_ProductDefinitionShape) aPDS =
212 Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti);
213 Handle(StepBasic_ProductDefinition) aProdDef;
215 if(aPDS.IsNull() == Standard_False) {
216 // Product Definition Shape ==> Product Definition
217 aProdDef = aPDS->Definition().ProductDefinition();
220 if (aProdDef.IsNull() == Standard_False) {
221 // Product Definition ==> Property Definition
222 const Interface_Graph &aGraph = theTP->Graph();
223 Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef);
226 for(aSubs.Start(); aSubs.More(); aSubs.Next()) {
227 Handle(StepRepr_PropertyDefinition) aPropD =
228 Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value());
230 if(aPropD.IsNull() == Standard_False) {
231 // Property Definition ==> Representation.
232 Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD);
234 for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) {
235 Handle(StepRepr_PropertyDefinitionRepresentation) aPDR =
236 Handle(StepRepr_PropertyDefinitionRepresentation)::
237 DownCast(aSubs1.Value());
239 if(aPDR.IsNull() == Standard_False) {
240 // Property Definition ==> Material Name.
241 Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation();
243 if(aRepr.IsNull() == Standard_False) {
246 for(ir = 1; ir <= aRepr->NbItems(); ir++) {
247 Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir);
248 Handle(StepRepr_DescriptiveRepresentationItem) aDRI =
249 Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI);
251 if(aDRI.IsNull() == Standard_False) {
252 // Get shape from Product Definition
253 Handle(TCollection_HAsciiString) aMatName = aDRI->Name();
255 if(aMatName.IsNull() == Standard_False) {
256 TCollection_ExtendedString
257 aMatNameExt (aMatName->ToCString());
259 if (aShape.IsNull()) {
261 aShape = GetShape(aProdDef, theTP);
263 if (aShape.IsNull()) {
268 // as PRODUCT can be included in the main shape
269 // several times, we look here for all iclusions.
270 Standard_Integer isub, nbSubs = theIndices.Extent();
272 for (isub = 1; isub <= nbSubs; isub++) {
273 TopoDS_Shape aSub = theIndices.FindKey(isub);
275 if (aSub.IsPartner(aShape)) {
277 GetLabel(aProdDef, theShapeLabel, aSub);
280 TDataStd_Comment::Set(aLabel, aMatNameExt);
294 //=============================================================================
298 //=============================================================================
300 Handle(TCollection_HAsciiString) GetValue (const TCollection_AsciiString& theFileName,
301 const TCollection_AsciiString& theParameterName,
302 TCollection_AsciiString& theError)
304 Handle(TCollection_HAsciiString) aValue;
306 if (theParameterName != "LEN_UNITS") {
307 theError = theParameterName + " parameter reading is not supported by STEP plugin";
311 // Set "C" numeric locale to save numbers correctly
312 // Kernel_Utils::Localizer loc;
314 STEPControl_Reader aReader;
316 Interface_Static::SetCVal("xstep.cascade.unit","M");
317 Interface_Static::SetIVal("read.step.ideas", 1);
318 Interface_Static::SetIVal("read.step.nonmanifold", 1);
321 #if OCC_VERSION_LARGE > 0x06010000
324 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.ToCString());
325 if (status == IFSelect_RetDone) {
326 TColStd_SequenceOfAsciiString anUnitLengthNames;
327 TColStd_SequenceOfAsciiString anUnitAngleNames;
328 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
329 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
330 if (anUnitLengthNames.Length() > 0) {
331 aValue = new TCollection_HAsciiString( anUnitLengthNames.First() );
333 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
334 if (aLenUnits == "millimetre")
335 aValue = new TCollection_HAsciiString ("MM");
336 else if (aLenUnits == "centimetre")
337 aValue = new TCollection_HAsciiString ("CM");
338 else if (aLenUnits == "metre")
339 aValue = new TCollection_HAsciiString ("M");
340 else if (aLenUnits == "INCH")
341 aValue = new TCollection_HAsciiString ("INCH");
342 // TODO (for other units than mm, cm, m or inch)
343 //else if (aLenUnits == "")
344 // aValue = new TCollection_HAsciiString ("");
347 //std::cout << "$$$ --- " << anUnitLengthNames.First();
348 //for (int ii = 2; ii <= anUnitLengthNames.Length(); ii++)
349 // std::cout << ", " << anUnitLengthNames.Value(ii);
350 //std::cout << std::endl;
356 theError = theFileName + " reading failed";
359 catch (Standard_Failure) {
360 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
361 theError = aFail->GetMessageString();
367 TopoDS_Shape Import (const TCollection_AsciiString& theFileName,
368 const TCollection_AsciiString& theFormatName,
369 TCollection_AsciiString& theError,
370 const TDF_Label& theShapeLabel)
372 TopoDS_Shape aResShape;
374 // Set "C" numeric locale to save numbers correctly
375 // Kernel_Utils::Localizer loc;
377 STEPControl_Reader aReader;
379 //VSR: 16/09/09: Convert to METERS
380 Interface_Static::SetCVal("xstep.cascade.unit","M");
381 Interface_Static::SetIVal("read.step.ideas", 1);
382 Interface_Static::SetIVal("read.step.nonmanifold", 1);
385 TopoDS_Compound compound;
386 B.MakeCompound(compound);
391 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.ToCString());
393 if (status == IFSelect_RetDone) {
395 // Regard or not the model units
396 if (theFormatName == "STEP_SCALE") {
397 // set UnitFlag to units from file
398 TColStd_SequenceOfAsciiString anUnitLengthNames;
399 TColStd_SequenceOfAsciiString anUnitAngleNames;
400 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
401 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
402 if (anUnitLengthNames.Length() > 0) {
403 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
404 if (aLenUnits == "millimetre")
405 Interface_Static::SetCVal("xstep.cascade.unit", "MM");
406 else if (aLenUnits == "centimetre")
407 Interface_Static::SetCVal("xstep.cascade.unit", "CM");
408 else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
409 Interface_Static::SetCVal("xstep.cascade.unit", "M");
410 else if (aLenUnits == "INCH")
411 Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
413 theError = "The file contains not supported units.";
416 // TODO (for other units than mm, cm, m or inch)
417 //else if (aLenUnits == "")
418 // Interface_Static::SetCVal("xstep.cascade.unit", "???");
422 //cout<<"need re-scale a model"<<endl;
423 // set UnitFlag to 'meter'
424 Interface_Static::SetCVal("xstep.cascade.unit","M");
427 Standard_Boolean failsonly = Standard_False;
428 aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
431 Standard_Integer nbr = aReader.NbRootsForTransfer();
432 aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
434 for (Standard_Integer n = 1; n <= nbr; n++) {
435 Standard_Boolean ok = aReader.TransferRoot(n);
436 /* Collecting resulting entities */
437 Standard_Integer nbs = aReader.NbShapes();
440 // THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM);
441 continue; // skip empty root
443 /* For a single entity */
444 else if (nbr == 1 && nbs == 1) {
445 aResShape = aReader.Shape(1);
446 // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
447 // It should be removed after patching OCCT for bug OCC22436
448 // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
449 if (aResShape.ShapeType() == TopAbs_COMPOUND) {
451 TopoDS_Shape currShape;
452 TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
453 for (; It.More(); It.Next()) {
455 currShape = It.Value();
458 aResShape = currShape;
464 for (Standard_Integer i = 1; i <= nbs; i++) {
465 TopoDS_Shape aShape = aReader.Shape(i);
466 if (aShape.IsNull()) {
467 // THROW_SALOME_CORBA_EXCEPTION("Null shape in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;
472 B.Add(compound, aShape);
476 if (aResShape.IsNull())
477 aResShape = compound;
479 // Check if any BRep entity has been read, there must be at least a vertex
480 if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
482 theError = "No geometrical data in the imported file.";
483 return TopoDS_Shape();
486 theError = "Wrong format of the imported file. Can't import file.";
490 catch (Standard_Failure) {
491 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
492 theError = aFail->GetMessageString();
495 // Return previous locale
499 } // namespace STEPImport