Salome HOME
Merge branch 'Dev_1.4.0' of newgeom:newgeom into Dev_1.4.0
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_STEPImport.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:    GEOMALGOAPI_STEPImport.cpp
4 // Created: Dec 24, 2014
5 // Author:  Sergey BELASH
6
7 #include <GeomAlgoAPI_STEPImport.h>
8
9 #include <TDF_ChildIDIterator.hxx>
10 #include <TDF_Label.hxx>
11 #include <TDataStd_Name.hxx>
12 #include <TDataStd_Comment.hxx>
13 #include <TNaming_Builder.hxx>
14 #include <TNaming_NamedShape.hxx>
15
16 #include <IFSelect_ReturnStatus.hxx>
17 #include <Interface_EntityIterator.hxx>
18 #include <Interface_Graph.hxx>
19 #include <Interface_InterfaceModel.hxx>
20 #include <Interface_Static.hxx>
21 #include <STEPControl_Reader.hxx>
22 #include <StepBasic_Product.hxx>
23 #include <StepBasic_ProductDefinition.hxx>
24 #include <StepBasic_ProductDefinitionFormation.hxx>
25 #include <StepGeom_GeometricRepresentationItem.hxx>
26 #include <StepShape_TopologicalRepresentationItem.hxx>
27 #include <StepRepr_DescriptiveRepresentationItem.hxx>
28 #include <StepRepr_ProductDefinitionShape.hxx>
29 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
30 #include <StepRepr_Representation.hxx>
31 #include <TransferBRep.hxx>
32 #include <Transfer_Binder.hxx>
33 #include <Transfer_TransientProcess.hxx>
34 #include <XSControl_TransferReader.hxx>
35 #include <XSControl_WorkSession.hxx>
36
37 #include <BRep_Builder.hxx>
38
39 #include <TopExp.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42 #include <TopoDS_Compound.hxx>
43 #include <TopoDS_Iterator.hxx>
44 #include <TopoDS_Shape.hxx>
45
46
47 #include <TColStd_SequenceOfAsciiString.hxx>
48
49 #include <Standard_Failure.hxx>
50 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
51 std::shared_ptr<GeomAPI_Shape> STEPImport(const std::string& theFileName,
52                                           const std::string& theFormatName,
53                                           std::string& theError)
54 {
55   TopoDS_Shape aResShape;
56
57   // Set "C" numeric locale to save numbers correctly
58   // Kernel_Utils::Localizer loc;
59
60   STEPControl_Reader aReader;
61
62   //VSR: 16/09/09: Convert to METERS
63   Interface_Static::SetCVal("xstep.cascade.unit","M");
64   Interface_Static::SetIVal("read.step.ideas", 1);
65   Interface_Static::SetIVal("read.step.nonmanifold", 1);
66
67   BRep_Builder B;
68   TopoDS_Compound compound;
69   B.MakeCompound(compound);
70
71   try {
72     OCC_CATCH_SIGNALS;
73
74     IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str());
75
76     if (status == IFSelect_RetDone) {
77
78       // Regard or not the model units
79       if (theFormatName == "STEP_SCALE") {
80         // set UnitFlag to units from file
81         TColStd_SequenceOfAsciiString anUnitLengthNames;
82         TColStd_SequenceOfAsciiString anUnitAngleNames;
83         TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
84         aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
85         if (anUnitLengthNames.Length() > 0) {
86           TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
87           if (aLenUnits == "millimetre")
88             Interface_Static::SetCVal("xstep.cascade.unit", "MM");
89           else if (aLenUnits == "centimetre")
90             Interface_Static::SetCVal("xstep.cascade.unit", "CM");
91           else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
92             Interface_Static::SetCVal("xstep.cascade.unit", "M");
93           else if (aLenUnits == "INCH")
94             Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
95           else {
96             theError = "The file contains not supported units.";
97             std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
98             aGeomShape->setImpl(new TopoDS_Shape(aResShape));
99             return aGeomShape;
100           }
101           // TODO (for other units than mm, cm, m or inch)
102           //else if (aLenUnits == "")
103           //  Interface_Static::SetCVal("xstep.cascade.unit", "???");
104         }
105       }
106       else {
107         //cout<<"need re-scale a model"<<endl;
108         // set UnitFlag to 'meter'
109         Interface_Static::SetCVal("xstep.cascade.unit","M");
110       }
111
112       Standard_Boolean failsonly = Standard_False;
113       aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
114
115       /* Root transfers */
116       Standard_Integer nbr = aReader.NbRootsForTransfer();
117       aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
118
119       for (Standard_Integer n = 1; n <= nbr; n++) {
120         Standard_Boolean ok = aReader.TransferRoot(n);
121         /* Collecting resulting entities */
122         Standard_Integer nbs = aReader.NbShapes();
123         if (!ok || nbs == 0)
124         {
125           // THROW_SALOME_CORBA_EXCEPTION("Exception catched in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM);
126           continue; // skip empty root
127         }
128         /* For a single entity */
129         else if (nbr == 1 && nbs == 1) {
130           aResShape = aReader.Shape(1);
131           // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
132           // It should be removed after patching OCCT for bug OCC22436
133           // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
134           if (aResShape.ShapeType() == TopAbs_COMPOUND) {
135             int nbSub1 = 0;
136             TopoDS_Shape currShape;
137             TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
138             for (; It.More(); It.Next()) {
139               nbSub1++;
140               currShape = It.Value();
141             }
142             if (nbSub1 == 1)
143               aResShape = currShape;
144           }
145           // END workaround
146           break;
147         }
148
149         for (Standard_Integer i = 1; i <= nbs; i++) {
150           TopoDS_Shape aShape = aReader.Shape(i);
151           if (aShape.IsNull()) {
152             // THROW_SALOME_CORBA_EXCEPTION("Null shape in GEOM_Gen_i::ImportStep", SALOME::BAD_PARAM) ;
153             //return aResShape;
154             continue;
155           }
156           else {
157             B.Add(compound, aShape);
158           }
159         }
160       }
161       if (aResShape.IsNull())
162         aResShape = compound;
163
164       // Check if any BRep entity has been read, there must be at least a vertex
165       if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
166       {
167         theError = "No geometrical data in the imported file.";
168         std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
169         aGeomShape->setImpl(new TopoDS_Shape());
170         return aGeomShape;
171       }
172     } else {
173       theError = "Wrong format of the imported file. Can't import file.";
174       aResShape.Nullify();
175     }
176   }
177   catch (Standard_Failure) {
178     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
179     theError = aFail->GetMessageString();
180     aResShape.Nullify();
181   }
182   // Return previous locale
183   std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
184   aGeomShape->setImpl(new TopoDS_Shape(aResShape));
185   return aGeomShape;
186 }