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