Salome HOME
Adding of list of shapes method added.
[modules/hydro.git] / src / HYDROData / HYDROData_Obstacle.cxx
1
2 #include "HYDROData_Obstacle.h"
3
4 #include "HYDROData_Document.h"
5 #include "HYDROData_ShapesGroup.h"
6 #include "HYDROData_ShapesTool.h"
7
8 #include <Basics_Utils.hxx>
9
10 #include <BRepTools.hxx>
11 #include <BRep_Builder.hxx>
12
13 #include <IGESControl_Reader.hxx>
14 #include <IGESData_IGESModel.hxx>
15
16 #include <STEPControl_Reader.hxx>
17
18 #include <Interface_Static.hxx>
19
20 #include <TopoDS.hxx>
21 #include <TopoDS_Iterator.hxx>
22 #include <TopoDS_Shape.hxx>
23 #include <TopoDS_Edge.hxx>
24
25 #include <TDataStd_AsciiString.hxx>
26
27 #include <TColStd_SequenceOfAsciiString.hxx>
28
29 #include <TopExp_Explorer.hxx>
30
31 #include <QColor>
32 #include <QFile>
33 #include <QFileInfo>
34 #include <QStringList>
35
36 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic
37
38 #include <HYDROData_Projection.h>
39
40 #define PYTHON_OBSTACLE_ID "KIND_OBSTACLE"
41
42 IMPLEMENT_STANDARD_HANDLE(HYDROData_Obstacle,HYDROData_ArtificialObject)
43 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Obstacle,HYDROData_ArtificialObject)
44
45
46 HYDROData_Obstacle::HYDROData_Obstacle()
47 : HYDROData_ArtificialObject()
48 {
49 }
50
51 HYDROData_Obstacle::~HYDROData_Obstacle()
52 {
53 }
54
55 QStringList HYDROData_Obstacle::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
56 {
57   QStringList aResList;
58
59   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
60   if ( aDocument.IsNull() )
61     return aResList;
62
63   QString aDocName = aDocument->GetDocPyName();
64   QString anObstacleName = GetName();
65
66   aResList << QString( "%1 = %2.CreateObject( %3 );" )
67               .arg( anObstacleName ).arg( aDocName ).arg( PYTHON_OBSTACLE_ID );
68   aResList << QString( "%1.SetName( \"%2\" );" )
69               .arg( anObstacleName ).arg( anObstacleName );
70   aResList << QString( "" );
71
72   // TODO
73
74   return aResList;
75 }
76
77 void HYDROData_Obstacle::Update()
78 {
79   removeGroupObjects();
80   createGroupObjects();
81   checkAndSetAltitudeObject();
82
83   HYDROData_Entity::Update();
84 }
85
86 TopoDS_Shape HYDROData_Obstacle::GetTopShape() const
87 {
88   return getTopShape();
89 }
90
91 TopoDS_Shape HYDROData_Obstacle::GetShape3D() const
92 {
93   return getShape3D();
94 }
95
96 void HYDROData_Obstacle::SetShape3D( const TopoDS_Shape& theShape )
97 {
98   TopoDS_Face aShape2d = HYDROData_Projection::MakeProjection( theShape );
99   HYDROData_ArtificialObject::SetShape3D( theShape );
100   HYDROData_ArtificialObject::SetTopShape( aShape2d );
101 }
102
103 QColor HYDROData_Obstacle::DefaultFillingColor()
104 {
105   return QColor( Qt::yellow );
106 }
107
108 QColor HYDROData_Obstacle::DefaultBorderColor()
109 {
110   return QColor( Qt::transparent );
111 }
112
113 bool HYDROData_Obstacle::ImportFromFile( const QString& theFilePath )
114 {
115   // Check the file existence
116   QFileInfo aFileInfo( theFilePath );
117   if ( !aFileInfo.exists() ) {
118     return false;
119   }
120
121   bool aRes = false;
122   TopoDS_Shape aShape;
123
124   // Import file
125   QString aFileSuf = aFileInfo.suffix().toLower();
126   if ( aFileSuf == "brep" ) {
127     aShape = ImportBREP( theFilePath );
128   } else if ( aFileSuf == "iges" || aFileSuf == "igs" ) {
129     aShape = ImportIGES( theFilePath );
130   } else if ( aFileSuf == "step" ) {
131     aShape = ImportSTEP( theFilePath );
132   }
133  
134   // Check the result shape
135   aRes = !aShape.IsNull();
136
137   // Set shape to the obstacle in case of success
138   if ( aRes ) {
139     SetShape3D( aShape );
140     SetFilePath( theFilePath );
141   }
142
143   return aRes;
144 }
145
146 void HYDROData_Obstacle::SetFilePath( const QString& theFilePath )
147 {
148   TCollection_AsciiString anAsciiStr( theFilePath.toStdString().c_str() );
149   TDataStd_AsciiString::Set( myLab.FindChild( DataTag_FilePath ), anAsciiStr );
150 }
151
152 QString HYDROData_Obstacle::GetFilePath() const
153 {
154   QString aRes;
155
156   Handle(TDataStd_AsciiString) anAsciiStr;
157   if ( myLab.FindChild( DataTag_FilePath ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
158     aRes = QString( anAsciiStr->Get().ToCString() );
159
160   return aRes;
161 }
162
163 void HYDROData_Obstacle::SetGeomObjectEntry( const QString& theEntry )
164 {
165   TCollection_AsciiString anAsciiStr( theEntry.toStdString().c_str() );
166   TDataStd_AsciiString::Set( myLab.FindChild( DataTag_GeomObjectEntry ), anAsciiStr );
167 }
168
169 QString HYDROData_Obstacle::GetGeomObjectEntry() const
170 {
171   QString aRes;
172
173   Handle(TDataStd_AsciiString) anAsciiStr;
174   if ( myLab.FindChild( DataTag_GeomObjectEntry ).FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) )
175     aRes = QString( anAsciiStr->Get().ToCString() );
176
177   return aRes;
178 }
179
180 TopoDS_Shape HYDROData_Obstacle::ImportBREP( const QString& theFilePath ) const
181 {
182   TopoDS_Shape aResShape;
183
184   BRep_Builder aBrepBuilder;
185   BRepTools::Read( aResShape, qPrintable(theFilePath), aBrepBuilder );
186
187   return aResShape;
188 }
189
190 TopoDS_Shape HYDROData_Obstacle::ImportIGES( const QString& theFilePath ) const
191 {
192   TopoDS_Shape aResShape;
193
194   // Set "C" numeric locale to save numbers correctly
195   Kernel_Utils::Localizer loc;
196
197   IGESControl_Reader aReader;
198
199   Interface_Static::SetCVal("xstep.cascade.unit","M");
200
201   try {
202     OCC_CATCH_SIGNALS;
203
204     IFSelect_ReturnStatus status = aReader.ReadFile(qPrintable(theFilePath));
205
206     if (status == IFSelect_RetDone) {
207       // Rescale units
208       Handle(IGESData_IGESModel) aModel =
209         Handle(IGESData_IGESModel)::DownCast(aReader.Model());
210       if (!aModel.IsNull()) {
211         IGESData_GlobalSection aGS = aModel->GlobalSection();
212         aGS.SetUnitFlag(6);
213         aModel->SetGlobalSection(aGS);
214       }
215     
216       aReader.ClearShapes();
217       aReader.TransferRoots();
218
219       aResShape = aReader.OneShape();
220     } 
221     else {
222       aResShape.Nullify();
223     }
224   }
225   catch(Standard_Failure) {
226     aResShape.Nullify();
227   }
228
229   return aResShape;
230 }
231
232 TopoDS_Shape HYDROData_Obstacle::ImportSTEP( const QString& theFilePath ) const
233 {
234   TopoDS_Shape aResShape;
235
236   // Set "C" numeric locale to save numbers correctly
237   Kernel_Utils::Localizer loc;
238
239   STEPControl_Reader aReader;
240
241   // Convert to METERS
242   Interface_Static::SetCVal("xstep.cascade.unit","M");
243   Interface_Static::SetIVal("read.step.ideas", 1);
244   Interface_Static::SetIVal("read.step.nonmanifold", 1);
245
246   BRep_Builder B;
247   TopoDS_Compound compound;
248   B.MakeCompound(compound);
249
250   try {
251     OCC_CATCH_SIGNALS;
252
253     IFSelect_ReturnStatus status = aReader.ReadFile( qPrintable(theFilePath) );
254
255     if (status == IFSelect_RetDone) {
256       // Rescale units
257       // set UnitFlag to units from file
258       TColStd_SequenceOfAsciiString anUnitLengthNames;
259       TColStd_SequenceOfAsciiString anUnitAngleNames;
260       TColStd_SequenceOfAsciiString anUnitSolidAngleNames;
261       aReader.FileUnits(anUnitLengthNames, anUnitAngleNames, anUnitSolidAngleNames);
262       if (anUnitLengthNames.Length() > 0) {
263         TCollection_AsciiString aLenUnits = anUnitLengthNames.First();
264         if (aLenUnits == "millimetre")
265           Interface_Static::SetCVal("xstep.cascade.unit", "MM");
266         else if (aLenUnits == "centimetre")
267           Interface_Static::SetCVal("xstep.cascade.unit", "CM");
268         else if (aLenUnits == "metre" || aLenUnits.IsEmpty())
269           Interface_Static::SetCVal("xstep.cascade.unit", "M");
270         else if (aLenUnits == "INCH")
271           Interface_Static::SetCVal("xstep.cascade.unit", "INCH");
272         else {
273           // The file contains not supported units
274           return aResShape;
275         }
276       }
277         
278       Standard_Boolean failsonly = Standard_False;
279       aReader.PrintCheckLoad(failsonly, IFSelect_ItemsByEntity);
280
281       // Root transfers
282       Standard_Integer nbr = aReader.NbRootsForTransfer();
283       aReader.PrintCheckTransfer(failsonly, IFSelect_ItemsByEntity);
284
285       for (Standard_Integer n = 1; n <= nbr; n++) {
286         Standard_Boolean ok = aReader.TransferRoot(n);
287         // Collecting resulting entities
288         Standard_Integer nbs = aReader.NbShapes();
289         if (!ok || nbs == 0) {
290           continue; // skip empty root
291         } 
292         else if (nbr == 1 && nbs == 1) { // For a single entity
293           aResShape = aReader.Shape(1);
294           // ATTENTION: this is a workaround for mantis issue 0020442 remark 0010776
295           // It should be removed after patching OCCT for bug OCC22436
296           // (fix for OCCT is expected in service pack next to OCCT6.3sp12)
297           if (aResShape.ShapeType() == TopAbs_COMPOUND) {
298             int nbSub1 = 0;
299             TopoDS_Shape currShape;
300             TopoDS_Iterator It (aResShape, Standard_True, Standard_True);
301             for (; It.More(); It.Next()) {
302               nbSub1++;
303               currShape = It.Value();
304             }
305             if (nbSub1 == 1)
306               aResShape = currShape;
307           }
308           // END workaround
309           break;
310         }
311
312         for (Standard_Integer i = 1; i <= nbs; i++) {
313           TopoDS_Shape aShape = aReader.Shape(i);
314           if (aShape.IsNull()) {
315             continue;
316           }
317           else {
318             B.Add(compound, aShape);
319           }
320         }
321       }
322   
323       if (aResShape.IsNull())
324         aResShape = compound;
325
326       // Check if any BRep entity has been read, there must be at least a vertex
327       if ( !TopExp_Explorer( aResShape, TopAbs_VERTEX ).More() ) {
328         // No geometrical data in the imported file
329         return TopoDS_Shape();
330       }
331     }
332     else {
333       aResShape.Nullify();
334     }
335   }
336   catch (Standard_Failure) {
337     aResShape.Nullify();
338   }
339
340   return aResShape;
341 }
342
343 QColor HYDROData_Obstacle::getDefaultFillingColor() const
344 {
345   return DefaultFillingColor();
346 }
347
348 QColor HYDROData_Obstacle::getDefaultBorderColor() const
349 {
350   return DefaultBorderColor();
351 }
352
353 void HYDROData_Obstacle::createGroupObjects()
354 {
355   TopoDS_Shape anObstacleShape = GetTopShape();
356   if ( !anObstacleShape.IsNull() )
357   {
358     TopTools_SequenceOfShape aWireEdges;
359     HYDROData_ShapesTool::ExploreShapeToShapes( anObstacleShape, TopAbs_EDGE, aWireEdges );
360     if ( !aWireEdges.IsEmpty() )
361     {
362       QString aWireGroupName = GetName() + "_Outer_Wire";
363
364       Handle(HYDROData_ShapesGroup) anExtWireGroup = createGroupObject();
365       anExtWireGroup->SetName( aWireGroupName );
366      
367       anExtWireGroup->SetShapes( aWireEdges );
368     }
369   }
370 }
371
372 ObjectKind HYDROData_Obstacle::getAltitudeObjectType() const
373 {
374   return KIND_OBSTACLE_ALTITUDE;
375 }
376
377
378