1 // Copyright (C) 2014-2020 CEA/DEN, EDF R&D
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
20 #include <GeomAlgoAPI_STEPImport.h>
21 #include <GeomAlgoAPI_STEPImportXCAF.h>
23 #include <TDF_ChildIDIterator.hxx>
24 #include <TDF_Label.hxx>
25 #include <TDataStd_Name.hxx>
26 #include <TDataStd_Comment.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_NamedShape.hxx>
30 #include <IFSelect_ReturnStatus.hxx>
31 #include <Interface_EntityIterator.hxx>
32 #include <Interface_Graph.hxx>
33 #include <Interface_InterfaceModel.hxx>
34 #include <Interface_Static.hxx>
36 #include <STEPCAFControl_Reader.hxx>
37 #include <STEPControl_Reader.hxx>
38 #include <StepBasic_Product.hxx>
39 #include <StepBasic_ProductDefinition.hxx>
40 #include <StepBasic_ProductDefinitionFormation.hxx>
41 #include <StepGeom_GeometricRepresentationItem.hxx>
42 #include <StepShape_TopologicalRepresentationItem.hxx>
43 #include <StepRepr_DescriptiveRepresentationItem.hxx>
44 #include <StepRepr_ProductDefinitionShape.hxx>
45 #include <StepRepr_PropertyDefinitionRepresentation.hxx>
46 #include <StepRepr_Representation.hxx>
47 #include <TransferBRep.hxx>
48 #include <Transfer_Binder.hxx>
49 #include <Transfer_TransientProcess.hxx>
50 #include <XSControl_TransferReader.hxx>
51 #include <XSControl_WorkSession.hxx>
53 #include <BRep_Builder.hxx>
56 #include <TopExp_Explorer.hxx>
57 #include <TopTools_IndexedMapOfShape.hxx>
58 #include <TopoDS_Compound.hxx>
59 #include <TopoDS_Iterator.hxx>
61 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
64 //==================================================================================================
65 std::shared_ptr<GeomAPI_Shape> STEPImport(const std::string& theFileName,
66 const std::string& theFormatName,
67 const bool theScalInterUnits,
68 std::string& theError)
71 TopoDS_Shape aResShape;
73 // Set "C" numeric locale to save numbers correctly
74 // Kernel_Utils::Localizer loc;
76 STEPControl_Reader aReader;
78 //VSR: 16/09/09: Convert to METERS
79 Interface_Static::SetCVal("xstep.cascade.unit","M");
80 Interface_Static::SetIVal("read.step.ideas", 1);
81 Interface_Static::SetIVal("read.step.nonmanifold", 1);
84 TopoDS_Compound compound;
85 B.MakeCompound(compound);
90 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str());
92 if (status == IFSelect_RetDone) {
94 // Regard or not the model units
95 if (!theScalInterUnits) {
96 // set UnitFlag to units from file
97 TColStd_SequenceOfAsciiString anUnitLengthNames;
98 TColStd_SequenceOfAsciiString anUnitAngleNames;
99 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
100 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
101 if (anUnitLengthNames.Length() > 0) {
102 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
103 if (aLenUnits == "millimetre")
104 Interface_Static::SetCVal("xstep.cascade.unit", "MM");
105 else if (aLenUnits == "centimetre")
106 Interface_Static::SetCVal("xstep.cascade.unit", "CM");
107 else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
108 Interface_Static::SetCVal("xstep.cascade.unit", "M");
109 else if (aLenUnits == "INCH")
110 Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
112 theError = "The file contains not supported units.";
113 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
114 aGeomShape->setImpl(new TopoDS_Shape(aResShape));
117 // TODO (for other units than mm, cm, m or inch)
118 //else if (aLenUnits == "")
119 // Interface_Static::SetCVal("xstep.cascade.unit", "???");
123 //cout<<"need re-scale a model"<<endl;
124 // set UnitFlag to 'meter'
125 Interface_Static::SetCVal("xstep.cascade.unit","M");
128 Standard_Boolean failsonly = Standard_False;
129 aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
132 Standard_Integer nbr = aReader.NbRootsForTransfer();
133 aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
135 for (Standard_Integer n = 1; n <= nbr; n++) {
136 Standard_Boolean ok = aReader.TransferRoot(n);
137 /* Collecting resulting entities */
138 Standard_Integer nbs = aReader.NbShapes();
141 continue; // skip empty root
143 /* For a single entity */
144 else if (nbr == 1 && nbs == 1) {
145 aResShape = aReader.Shape(1);
146 // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
147 // It should be removed after patching OCCT for bug OCC22436
148 // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
149 if (aResShape.ShapeType() == TopAbs_COMPOUND) {
151 TopoDS_Shape currShape;
152 TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
153 for (; It.More(); It.Next()) {
155 currShape = It.Value();
158 aResShape = currShape;
164 for (Standard_Integer i = 1; i <= nbs; i++) {
165 TopoDS_Shape aShape = aReader.Shape(i);
166 if (aShape.IsNull()) {
171 B.Add(compound, aShape);
175 if (aResShape.IsNull())
176 aResShape = compound;
178 // Check if any BRep entity has been read, there must be at least a vertex
179 if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() )
181 theError = "No geometrical data in the imported file.";
182 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
183 aGeomShape->setImpl(new TopoDS_Shape());
187 theError = "Wrong format of the imported file. Can't import file.";
191 catch (Standard_Failure const& anException) {
192 theError = anException.GetMessageString();
195 // Return previous locale
196 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
197 aGeomShape->setImpl(new TopoDS_Shape(aResShape));
201 //==================================================================================================
202 GeomShapePtr STEPImportAttributs(const std::string& theFileName,
203 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
204 const bool theScalInterUnits,
205 const bool theMaterials,
207 std::map< std::wstring,
208 std::list<std::wstring>>& theMaterialShape,
209 std::string& theError)
212 STEPControl_Reader aReader;
213 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
215 Interface_Static::SetCVal("xstep.cascade.unit","M");
216 Interface_Static::SetIVal("read.step.ideas", 1);
217 Interface_Static::SetIVal("read.step.nonmanifold", 1);
222 IFSelect_ReturnStatus status = aReader.ReadFile(theFileName.c_str());
224 if (status == IFSelect_RetDone) {
226 // Regard or not the model units
227 if (!theScalInterUnits) {
228 // set UnitFlag to units from file
229 TColStd_SequenceOfAsciiString anUnitLengthNames;
230 TColStd_SequenceOfAsciiString anUnitAngleNames;
231 TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
232 aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
233 if (anUnitLengthNames.Length() > 0) {
234 TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
235 if (aLenUnits == "millimetre")
236 Interface_Static::SetCVal("xstep.cascade.unit", "MM");
237 else if (aLenUnits == "centimetre")
238 Interface_Static::SetCVal("xstep.cascade.unit", "CM");
239 else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
240 Interface_Static::SetCVal("xstep.cascade.unit", "M");
241 else if (aLenUnits == "INCH")
242 Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
244 theError = "The file contains not supported units.";
245 aGeomShape->setImpl(new TopoDS_Shape());
248 // TODO (for other units than mm, cm, m or inch)
249 //else if (aLenUnits == "")
250 // Interface_Static::SetCVal("xstep.cascade.unit", "???");
254 //cout<<"need re-scale a model"<<endl;
255 // set UnitFlag to 'meter'
256 Interface_Static::SetCVal("xstep.cascade.unit","M");
260 catch (Standard_Failure const& anException) {
261 theError = anException.GetMessageString();
262 aGeomShape->setImpl(new TopoDS_Shape());
266 STEPCAFControl_Reader aCafreader;
267 aCafreader.SetColorMode(true);
268 aCafreader.SetNameMode(true);
269 aCafreader.SetMatMode(true);
271 if(aCafreader.ReadFile(theFileName.c_str()) != IFSelect_RetDone) {
272 theError = "Wrong format of the imported file. Can't import file.";
273 std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape);
274 aGeomShape->setImpl(new TopoDS_Shape());
278 return readAttributes(aCafreader,