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 //=============================================================================
50 //=============================================================================
52 static TopoDS_Shape GetShape(const Handle(Standard_Transient) &theEnti,
53 const Handle(Transfer_TransientProcess) &theTP)
56 Handle(Transfer_Binder) aBinder = theTP->Find(theEnti);
58 if (aBinder.IsNull()) {
62 aResult = TransferBRep::ShapeResult(aBinder);
67 //=============================================================================
71 //=============================================================================
73 static TDF_Label GetLabel(const Handle(Standard_Transient) &theEnti,
74 const TDF_Label &theShapeLabel,
75 const TopoDS_Shape &aShape)
80 (STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
81 // check all named shapes using iterator
82 TDF_ChildIDIterator anIt
83 (theShapeLabel, TDataStd_Name::GetID(), Standard_True);
85 for (; anIt.More(); anIt.Next()) {
86 Handle(TDataStd_Name) nameAttr =
87 Handle(TDataStd_Name)::DownCast(anIt.Value());
89 if (nameAttr.IsNull()) {
93 TDF_Label aLab = nameAttr->Label();
94 Handle(TNaming_NamedShape) shAttr;
96 if (aLab.FindAttribute(TNaming_NamedShape::GetID(), shAttr) &&
97 shAttr->Get().IsEqual(aShape)) {
103 // create label and set shape
104 if (aResult.IsNull()) {
107 aResult = aTag.NewChild(theShapeLabel);
109 TNaming_Builder tnBuild (aResult);
111 tnBuild.Generated(aShape);
117 //=============================================================================
121 //=============================================================================
123 static void StoreName(const Handle(Standard_Transient) &theEnti,
124 const TopTools_IndexedMapOfShape &theIndices,
125 const Handle(Transfer_TransientProcess) &theTP,
126 const TDF_Label &theShapeLabel)
128 Handle(TCollection_HAsciiString) aName;
130 if (theEnti->IsKind(STANDARD_TYPE(StepShape_TopologicalRepresentationItem)) ||
131 theEnti->IsKind(STANDARD_TYPE(StepGeom_GeometricRepresentationItem))) {
132 aName = Handle(StepRepr_RepresentationItem)::DownCast(theEnti)->Name();
134 Handle(StepBasic_ProductDefinition) PD =
135 Handle(StepBasic_ProductDefinition)::DownCast(theEnti);
137 if (PD.IsNull() == Standard_False) {
138 Handle(StepBasic_Product) Prod = PD->Formation()->OfProduct();
139 aName = Prod->Name();
143 bool isValidName = false;
145 if (aName.IsNull() == Standard_False) {
148 if (aName->UsefullLength() < 1) {
150 } else if (aName->UsefullLength() == 4 &&
151 toupper (aName->Value(1)) == 'N' &&
152 toupper (aName->Value(2)) == 'O' &&
153 toupper (aName->Value(3)) == 'N' &&
154 toupper (aName->Value(4)) == 'E') {
158 // special check to pass names like "Open CASCADE STEP translator 6.3 1"
159 TCollection_AsciiString aSkipName ("Open CASCADE STEP translator");
161 if (aName->Length() >= aSkipName.Length()) {
162 if (aName->String().SubString
163 (1, aSkipName.Length()).IsEqual(aSkipName)) {
171 TCollection_ExtendedString aNameExt (aName->ToCString());
174 TopoDS_Shape S = GetShape(theEnti, theTP);
180 // as PRODUCT can be included in the main shape
181 // several times, we look here for all iclusions.
182 Standard_Integer isub, nbSubs = theIndices.Extent();
184 for (isub = 1; isub <= nbSubs; isub++) {
185 TopoDS_Shape aSub = theIndices.FindKey(isub);
187 if (aSub.IsPartner(S)) {
188 TDF_Label L = GetLabel(theEnti, theShapeLabel, aSub);
191 TDataStd_Name::Set(L, aNameExt);
197 //=============================================================================
201 //=============================================================================
203 static void StoreMaterial
204 (const Handle(Standard_Transient) &theEnti,
205 const TopTools_IndexedMapOfShape &theIndices,
206 const Handle(Transfer_TransientProcess) &theTP,
207 const TDF_Label &theShapeLabel)
209 // Treat Product Definition Shape only.
210 Handle(StepRepr_ProductDefinitionShape) aPDS =
211 Handle(StepRepr_ProductDefinitionShape)::DownCast(theEnti);
212 Handle(StepBasic_ProductDefinition) aProdDef;
214 if(aPDS.IsNull() == Standard_False) {
215 // Product Definition Shape ==> Product Definition
216 aProdDef = aPDS->Definition().ProductDefinition();
219 if (aProdDef.IsNull() == Standard_False) {
220 // Product Definition ==> Property Definition
221 const Interface_Graph &aGraph = theTP->Graph();
222 Interface_EntityIterator aSubs = aGraph.Sharings(aProdDef);
225 for(aSubs.Start(); aSubs.More(); aSubs.Next()) {
226 Handle(StepRepr_PropertyDefinition) aPropD =
227 Handle(StepRepr_PropertyDefinition)::DownCast(aSubs.Value());
229 if(aPropD.IsNull() == Standard_False) {
230 // Property Definition ==> Representation.
231 Interface_EntityIterator aSubs1 = aGraph.Sharings(aPropD);
233 for(aSubs1.Start(); aSubs1.More(); aSubs1.Next()) {
234 Handle(StepRepr_PropertyDefinitionRepresentation) aPDR =
235 Handle(StepRepr_PropertyDefinitionRepresentation)::
236 DownCast(aSubs1.Value());
238 if(aPDR.IsNull() == Standard_False) {
239 // Property Definition ==> Material Name.
240 Handle(StepRepr_Representation) aRepr = aPDR->UsedRepresentation();
242 if(aRepr.IsNull() == Standard_False) {
245 for(ir = 1; ir <= aRepr->NbItems(); ir++) {
246 Handle(StepRepr_RepresentationItem) aRI = aRepr->ItemsValue(ir);
247 Handle(StepRepr_DescriptiveRepresentationItem) aDRI =
248 Handle(StepRepr_DescriptiveRepresentationItem)::DownCast(aRI);
250 if(aDRI.IsNull() == Standard_False) {
251 // Get shape from Product Definition
252 Handle(TCollection_HAsciiString) aMatName = aDRI->Name();
254 if(aMatName.IsNull() == Standard_False) {
255 TCollection_ExtendedString
256 aMatNameExt (aMatName->ToCString());
258 if (aShape.IsNull()) {
260 aShape = GetShape(aProdDef, theTP);
262 if (aShape.IsNull()) {
267 // as PRODUCT can be included in the main shape
268 // several times, we look here for all iclusions.
269 Standard_Integer isub, nbSubs = theIndices.Extent();
271 for (isub = 1; isub <= nbSubs; isub++) {
272 TopoDS_Shape aSub = theIndices.FindKey(isub);
274 if (aSub.IsPartner(aShape)) {
276 GetLabel(aProdDef, theShapeLabel, aSub);
279 TDataStd_Comment::Set(aLabel, aMatNameExt);
293 //=============================================================================
297 //=============================================================================
299 Handle(TCollection_HAsciiString) GetValue (const TCollection_AsciiString& theFileName,
300 const TCollection_AsciiString& theParameterName,
301 TCollection_AsciiString& theError)
303 Handle(TCollection_HAsciiString) aValue;
305 if (theParameterName != "LEN_UNITS") {
306 theError = theParameterName + " parameter reading is not supported by STEP plugin";
310 // Set "C" numeric locale to save numbers correctly
311 // Kernel_Utils::Localizer loc;
313 STEPControl_Reader aReader;
315 Interface_Static::SetCVal("xstep.cascade.unit","M");
316 Interface_Static::SetIVal("read.step.ideas", 1);
317 Interface_Static::SetIVal("read.step.nonmanifold", 1);
320 #if OCC_VERSION_LARGE > 0x06010000
323 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.ToCString());
324 if (status == IFSelect_RetDone) {
325 TColStd_SequenceOfAsciiString anUnitLengthNames;
326 TColStd_SequenceOfAsciiString anUnitAngleNames;
327 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
328 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
329 if (anUnitLengthNames.Length() > 0) {
330 aValue = new TCollection_HAsciiString( anUnitLengthNames.First() );
332 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
333 if (aLenUnits == "millimetre")
334 aValue = new TCollection_HAsciiString ("MM");
335 else if (aLenUnits == "centimetre")
336 aValue = new TCollection_HAsciiString ("CM");
337 else if (aLenUnits == "metre")
338 aValue = new TCollection_HAsciiString ("M");
339 else if (aLenUnits == "INCH")
340 aValue = new TCollection_HAsciiString ("INCH");
341 // TODO (for other units than mm, cm, m or inch)
342 //else if (aLenUnits == "")
343 // aValue = new TCollection_HAsciiString ("");
346 //std::cout << "$$$ --- " << anUnitLengthNames.First();
347 //for (int ii = 2; ii <= anUnitLengthNames.Length(); ii++)
348 // std::cout << ", " << anUnitLengthNames.Value(ii);
349 //std::cout << std::endl;
355 theError = theFileName + " reading failed";
358 catch (Standard_Failure) {
359 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
360 theError = aFail->GetMessageString();
366 TopoDS_Shape STEPImport(const std::string& theFileName,
367 const std::string& theFormatName,
368 std::string& theError)
370 TopoDS_Shape aResShape;
372 // Set "C" numeric locale to save numbers correctly
373 // Kernel_Utils::Localizer loc;
375 STEPControl_Reader aReader;
377 //VSR: 16/09/09: Convert to METERS
378 Interface_Static::SetCVal("xstep.cascade.unit","M");
379 Interface_Static::SetIVal("read.step.ideas", 1);
380 Interface_Static::SetIVal("read.step.nonmanifold", 1);
383 TopoDS_Compound compound;
384 B.MakeCompound(compound);
389 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str());
391 if (status == IFSelect_RetDone) {
393 // Regard or not the model units
394 if (theFormatName == "STEP_SCALE") {
395 // set UnitFlag to units from file
396 TColStd_SequenceOfAsciiString anUnitLengthNames;
397 TColStd_SequenceOfAsciiString anUnitAngleNames;
398 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
399 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
400 if (anUnitLengthNames.Length() > 0) {
401 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
402 if (aLenUnits == "millimetre")
403 Interface_Static::SetCVal("xstep.cascade.unit", "MM");
404 else if (aLenUnits == "centimetre")
405 Interface_Static::SetCVal("xstep.cascade.unit", "CM");
406 else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
407 Interface_Static::SetCVal("xstep.cascade.unit", "M");
408 else if (aLenUnits == "INCH")
409 Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
411 theError = "The file contains not supported units.";
414 // TODO (for other units than mm, cm, m or inch)
415 //else if (aLenUnits == "")
416 // Interface_Static::SetCVal("xstep.cascade.unit", "???");
420 //cout<<"need re-scale a model"<<endl;
421 // set UnitFlag to 'meter'
422 Interface_Static::SetCVal("xstep.cascade.unit","M");
425 Standard_Boolean failsonly = Standard_False;
426 aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
429 Standard_Integer nbr = aReader.NbRootsForTransfer();
430 aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
432 for (Standard_Integer n = 1; n <= nbr; n++) {
433 Standard_Boolean ok = aReader.TransferRoot(n);
434 /* Collecting resulting entities */
435 Standard_Integer nbs = aReader.NbShapes();
438 // THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM);
439 continue; // skip empty root
441 /* For a single entity */
442 else if (nbr == 1 && nbs == 1) {
443 aResShape = aReader.Shape(1);
444 // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
445 // It should be removed after patching OCCT for bug OCC22436
446 // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
447 if (aResShape.ShapeType() == TopAbs_COMPOUND) {
449 TopoDS_Shape currShape;
450 TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
451 for (; It.More(); It.Next()) {
453 currShape = It.Value();
456 aResShape = currShape;
462 for (Standard_Integer i = 1; i <= nbs; i++) {
463 TopoDS_Shape aShape = aReader.Shape(i);
464 if (aShape.IsNull()) {
465 // THROW_SALOME_CORBA_EXCEPTION("Null shape in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;
470 B.Add(compound, aShape);
474 if (aResShape.IsNull())
475 aResShape = compound;
477 // Check if any BRep entity has been read, there must be at least a vertex
478 if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
480 theError = "No geometrical data in the imported file.";
481 return TopoDS_Shape();
484 theError = "Wrong format of the imported file. Can't import file.";
488 catch (Standard_Failure) {
489 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
490 theError = aFail->GetMessageString();
493 // Return previous locale