0031279: Visualization, TKOpenGl - environment background is misplaced within Ray...
[occt.git] / src / RWMesh / RWMesh_CafReader.hxx
1 // Author: Kirill Gavrilov
2 // Copyright (c) 2016-2019 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _RWMesh_CafReader_HeaderFile
16 #define _RWMesh_CafReader_HeaderFile
17
18 #include <NCollection_IndexedMap.hxx>
19 #include <RWMesh_CoordinateSystemConverter.hxx>
20 #include <RWMesh_NodeAttributes.hxx>
21 #include <TColStd_IndexedDataMapOfStringString.hxx>
22 #include <TDF_Label.hxx>
23 #include <TopTools_SequenceOfShape.hxx>
24
25 class Message_ProgressIndicator;
26 class TDocStd_Document;
27 class XCAFDoc_ShapeTool;
28 class XCAFDoc_ColorTool;
29 class XCAFDoc_VisMaterialTool;
30
31 //! Extended status bits.
32 enum RWMesh_CafReaderStatusEx
33 {
34   RWMesh_CafReaderStatusEx_NONE    = 0,    //!< empty status
35   RWMesh_CafReaderStatusEx_Partial = 0x01, //!< partial read (due to unexpected EOF, syntax error, memory limit)
36 };
37
38 //! The general interface for importing mesh data into XDE document.
39 //!
40 //! The tool implements auxiliary structures for creating an XDE document in two steps:
41 //! 1) Creating TopoDS_Shape hierarchy (myRootShapes)
42 //!    and Shape attributes (myAttribMap) separately within performMesh().
43 //!    Attributes include names and styles.
44 //! 2) Filling XDE document from these auxiliary structures.
45 //!    Named elements are expanded within document structure, while Compounds having no named children will remain collapsed.
46 //!    In addition, unnamed nodes can be filled with generated names like "Face", "Compound" via generateNames() method,
47 //!    and the very root unnamed node can be filled from file name like "MyModel.obj".
48 class RWMesh_CafReader : public Standard_Transient
49 {
50   DEFINE_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
51 public:
52
53   //! Structure holding tools for filling the document.
54   struct CafDocumentTools
55   {
56     Handle(XCAFDoc_ShapeTool)       ShapeTool;
57     Handle(XCAFDoc_ColorTool)       ColorTool;
58     Handle(XCAFDoc_VisMaterialTool) VisMaterialTool;
59     NCollection_DataMap<TopoDS_Shape, TDF_Label, TopTools_ShapeMapHasher> ComponentMap;
60   };
61
62 public:
63
64   //! Empty constructor.
65   Standard_EXPORT RWMesh_CafReader();
66
67   //! Destructor.
68   Standard_EXPORT virtual ~RWMesh_CafReader();
69
70   //! Return target document.
71   const Handle(TDocStd_Document)& Document() const { return myXdeDoc; }
72
73   //! Set target document.
74   void SetDocument (const Handle(TDocStd_Document)& theDoc) { myXdeDoc = theDoc; }
75
76   //! Return prefix for generating root labels names.
77   const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; }
78
79   //! Set prefix for generating root labels names
80   void SetRootPrefix (const TCollection_AsciiString& theRootPrefix) { myRootPrefix = theRootPrefix; }
81
82   //! Flag indicating if partially read file content should be put into the XDE document, TRUE by default.
83   //!
84   //! Partial read means unexpected end of file, critical parsing syntax errors in the middle of file, or reached memory limit
85   //! indicated by performMesh() returning FALSE.
86   //! Partial read allows importing a model even in case of formal reading failure,
87   //! so that it will be up to user to decide if processed data has any value.
88   //!
89   //! In case of partial read (performMesh() returns FALSE, but there are some data that could be put into document),
90   //! Perform() will return TRUE and result flag will have failure bit set.
91   //! @sa MemoryLimitMiB(), ExtraStatus().
92   Standard_Boolean ToFillIncompleteDocument() const { return myToFillIncomplete; }
93
94   //! Set flag allowing partially read file content to be put into the XDE document.
95   void SetFillIncompleteDocument (Standard_Boolean theToFillIncomplete) { myToFillIncomplete = theToFillIncomplete; }
96
97   //! Return memory usage limit in MiB, -1 by default which means no limit.
98   Standard_Integer MemoryLimitMiB() const { return myMemoryLimitMiB; }
99
100   //! Set memory usage limit in MiB; can be ignored by reader implementation!
101   void SetMemoryLimitMiB (Standard_Integer theLimitMiB) { myMemoryLimitMiB = theLimitMiB; }
102
103 public:
104
105   //! Return coordinate system converter.
106   const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCoordSysConverter; }
107
108   //! Set coordinate system converter.
109   void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCoordSysConverter = theConverter; }
110
111   //! Return the length unit to convert into while reading the file, defined as scale factor for m (meters);
112   //! -1.0 by default, which means that NO conversion will be applied.
113   Standard_Real SystemLengthUnit() const { return myCoordSysConverter.OutputLengthUnit(); }
114
115   //! Set system length units to convert into while reading the file, defined as scale factor for m (meters).
116   void SetSystemLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetOutputLengthUnit (theUnits); }
117
118   //! Return TRUE if system coordinate system has been defined; FALSE by default.
119   Standard_Boolean HasSystemCoordinateSystem() const { return myCoordSysConverter.HasOutputCoordinateSystem(); }
120
121   //! Return system coordinate system; UNDEFINED by default, which means that no conversion will be done.
122   const gp_Ax3& SystemCoordinateSystem() const { return myCoordSysConverter.OutputCoordinateSystem(); }
123
124   //! Set system origin coordinate system to perform conversion into during read.
125   void SetSystemCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
126
127   //! Set system origin coordinate system to perform conversion into during read.
128   void SetSystemCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
129
130   //! Return the length unit to convert from while reading the file, defined as scale factor for m (meters).
131   //! Can be undefined (-1.0) if file format is unitless.
132   Standard_Real FileLengthUnit() const { return myCoordSysConverter.InputLengthUnit(); }
133
134   //! Set (override) file length units to convert from while reading the file, defined as scale factor for m (meters).
135   void SetFileLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetInputLengthUnit (theUnits); }
136
137   //! Return TRUE if file origin coordinate system has been defined.
138   Standard_Boolean HasFileCoordinateSystem() const { return myCoordSysConverter.HasInputCoordinateSystem(); }
139
140   //! Return file origin coordinate system; can be UNDEFINED, which means no conversion will be done.
141   const gp_Ax3& FileCoordinateSystem() const { return myCoordSysConverter.InputCoordinateSystem(); }
142
143   //! Set (override) file origin coordinate system to perform conversion during read.
144   void SetFileCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
145
146   //! Set (override) file origin coordinate system to perform conversion during read.
147   void SetFileCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
148
149 public:
150
151   //! Read the data from specified file.
152   //! The Document instance should be set beforehand.
153   bool Perform (const TCollection_AsciiString& theFile,
154                 const Handle(Message_ProgressIndicator)& theProgress)
155   {
156     return perform (theFile, theProgress, Standard_False);
157   }
158
159   //! Return extended status flags.
160   //! @sa RWMesh_CafReaderStatusEx enumeration.
161   Standard_Integer ExtraStatus() const { return myExtraStatus; }
162
163 public:
164
165   //! Return result as a single shape.
166   Standard_EXPORT TopoDS_Shape SingleShape() const;
167
168   //! Return the list of complementary files - external references (textures, data, etc.).
169   const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const { return myExternalFiles; }
170
171   //! Return metadata map.
172   const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; }
173
174   //! Read the header data from specified file without reading entire model.
175   //! The main purpose is collecting metadata and external references - for copying model into a new location, for example.
176   //! Can be NOT implemented (unsupported by format / reader).
177   Standard_Boolean ProbeHeader (const TCollection_AsciiString& theFile,
178                                 const Handle(Message_ProgressIndicator)& theProgress = Handle(Message_ProgressIndicator)())
179   {
180     return perform (theFile, theProgress, Standard_True);
181   }
182
183 protected:
184
185   //! Read the data from specified file.
186   //! Default implementation calls performMesh() and fills XDE document from collected shapes.
187   //! @param theFile    file to read
188   //! @param optional   progress indicator
189   //! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read
190   Standard_EXPORT virtual Standard_Boolean perform (const TCollection_AsciiString& theFile,
191                                                     const Handle(Message_ProgressIndicator)& theProgress,
192                                                     const Standard_Boolean theToProbe);
193
194   //! Read the mesh from specified file - interface to be implemented by sub-classes.
195   Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
196                                                         const Handle(Message_ProgressIndicator)& theProgress,
197                                                         const Standard_Boolean theToProbe) = 0;
198
199 //! @name tools for filling XDE document
200 protected:
201
202   //! Fill document with new root shapes.
203   Standard_EXPORT void fillDocument();
204
205   //! Append new shape into the document (recursively).
206   Standard_EXPORT Standard_Boolean addShapeIntoDoc (CafDocumentTools& theTools,
207                                                     const TopoDS_Shape& theShape,
208                                                     const TDF_Label& theLabel,
209                                                     const TCollection_AsciiString& theParentName);
210
211   //! Append new sub-shape into the document (recursively).
212   Standard_EXPORT Standard_Boolean addSubShapeIntoDoc (CafDocumentTools& theTools,
213                                                        const TopoDS_Shape& theShape,
214                                                        const TDF_Label& theParentLabel,
215                                                        const RWMesh_NodeAttributes& theAttribs);
216
217   //! Put name attribute onto the label.
218   Standard_EXPORT void setShapeName (const TDF_Label& theLabel,
219                                      const TopAbs_ShapeEnum theShapeType,
220                                      const TCollection_AsciiString& theName,
221                                      const TDF_Label& theParentLabel,
222                                      const TCollection_AsciiString& theParentName);
223
224   //! Put color and material attributes onto the label.
225   Standard_EXPORT void setShapeStyle (const CafDocumentTools& theTools,
226                                       const TDF_Label& theLabel,
227                                       const XCAFPrs_Style& theStyle);
228
229   //! Put name data (metadata) attribute onto the label.
230   Standard_EXPORT void setShapeNamedData (const CafDocumentTools& theTools,
231                                           const TDF_Label& theLabel,
232                                           const Handle(TDataStd_NamedData)& theNameData);
233
234   //! Generate names for root labels starting from specified index.
235   Standard_EXPORT void generateNames (const TCollection_AsciiString& theFile,
236                                       const Standard_Integer theRootLower,
237                                       const Standard_Boolean theWithSubLabels);
238
239   //! Return shape type as string.
240   //! @sa TopAbs::ShapeTypeToString()
241   static TCollection_AsciiString shapeTypeToString (TopAbs_ShapeEnum theType)
242   {
243     TCollection_AsciiString aString = TopAbs::ShapeTypeToString (theType);
244     aString.Capitalize();
245     return aString;
246   }
247
248 protected:
249
250   Handle(TDocStd_Document)  myXdeDoc;            //!< target document
251
252   TColStd_IndexedDataMapOfStringString
253                             myMetadata;          //!< metadata map
254   NCollection_IndexedMap<TCollection_AsciiString>
255                             myExternalFiles;     //!< the list of complementary files - external references (textures, data, etc.)
256   TCollection_AsciiString   myRootPrefix;        //!< root folder for generating root labels names
257   TopTools_SequenceOfShape  myRootShapes;        //!< sequence of result root shapes
258   RWMesh_NodeAttributeMap   myAttribMap;         //!< map of per-shape attributes
259
260   RWMesh_CoordinateSystemConverter
261                             myCoordSysConverter; //!< coordinate system converter
262   Standard_Boolean          myToFillDoc;         //!< fill document from shape sequence
263   Standard_Boolean          myToFillIncomplete;  //!< fill the document with partially retrieved data even if reader has failed with error
264   Standard_Integer          myMemoryLimitMiB;    //!< memory usage limit
265   Standard_Integer          myExtraStatus;       //!< extra status bitmask
266
267 };
268
269 #endif // _RWMesh_CafReader_HeaderFile