0030692: Data Exchange - introduce base framework RWMesh for importing mesh data...
[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
28 //! Extended status bits.
29 enum RWMesh_CafReaderStatusEx
30 {
31   RWMesh_CafReaderStatusEx_NONE    = 0,    //!< empty status
32   RWMesh_CafReaderStatusEx_Partial = 0x01, //!< partial read (due to unexpected EOF, syntax error, memory limit)
33 };
34
35 //! The general interface for importing mesh data into XDE document.
36 //!
37 //! The tool implements auxiliary structures for creating an XDE document in two steps:
38 //! 1) Creating TopoDS_Shape hierarchy (myRootShapes)
39 //!    and Shape attributes (myAttribMap) separately within performMesh().
40 //!    Attributes include names and styles.
41 //! 2) Filling XDE document from these auxiliary structures.
42 //!    Named elements are expanded within document structure, while Compounds having no named children will remain collapsed.
43 //!    In addition, unnamed nodes can be filled with generated names like "Face", "Compound" via generateNames() method,
44 //!    and the very root unnamed node can be filled from file name like "MyModel.obj".
45 class RWMesh_CafReader : public Standard_Transient
46 {
47   DEFINE_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
48 public:
49
50   //! Empty constructor.
51   Standard_EXPORT RWMesh_CafReader();
52
53   //! Destructor.
54   Standard_EXPORT virtual ~RWMesh_CafReader();
55
56   //! Return target document.
57   const Handle(TDocStd_Document)& Document() const { return myXdeDoc; }
58
59   //! Set target document.
60   void SetDocument (const Handle(TDocStd_Document)& theDoc) { myXdeDoc = theDoc; }
61
62   //! Return prefix for generating root labels names.
63   const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; }
64
65   //! Set prefix for generating root labels names
66   void SetRootPrefix (const TCollection_AsciiString& theRootPrefix) { myRootPrefix = theRootPrefix; }
67
68   //! Flag indicating if partially read file content should be put into the XDE document, TRUE by default.
69   //!
70   //! Partial read means unexpected end of file, critical parsing syntax errors in the middle of file, or reached memory limit
71   //! indicated by performMesh() returning FALSE.
72   //! Partial read allows importing a model even in case of formal reading failure,
73   //! so that it will be up to user to decide if processed data has any value.
74   //!
75   //! In case of partial read (performMesh() returns FALSE, but there are some data that could be put into document),
76   //! Perform() will return TRUE and result flag will have failure bit set.
77   //! @sa MemoryLimitMiB(), ExtraStatus().
78   Standard_Boolean ToFillIncompleteDocument() const { return myToFillIncomplete; }
79
80   //! Set flag allowing partially read file content to be put into the XDE document.
81   void SetFillIncompleteDocument (Standard_Boolean theToFillIncomplete) { myToFillIncomplete = theToFillIncomplete; }
82
83   //! Return memory usage limit in MiB, -1 by default which means no limit.
84   Standard_Integer MemoryLimitMiB() const { return myMemoryLimitMiB; }
85
86   //! Set memory usage limit in MiB; can be ignored by reader implementation!
87   void SetMemoryLimitMiB (Standard_Integer theLimitMiB) { myMemoryLimitMiB = theLimitMiB; }
88
89 public:
90
91   //! Return coordinate system converter.
92   const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCoordSysConverter; }
93
94   //! Set coordinate system converter.
95   void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCoordSysConverter = theConverter; }
96
97   //! Return the length unit to convert into while reading the file, defined as scale factor for m (meters);
98   //! -1.0 by default, which means that NO conversion will be applied.
99   Standard_Real SystemLengthUnit() const { return myCoordSysConverter.OutputLengthUnit(); }
100
101   //! Set system length units to convert into while reading the file, defined as scale factor for m (meters).
102   void SetSystemLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetOutputLengthUnit (theUnits); }
103
104   //! Return TRUE if system coordinate system has been defined; FALSE by default.
105   Standard_Boolean HasSystemCoordinateSystem() const { return myCoordSysConverter.HasOutputCoordinateSystem(); }
106
107   //! Return system coordinate system; UNDEFINED by default, which means that no conversion will be done.
108   const gp_Ax3& SystemCoordinateSystem() const { return myCoordSysConverter.OutputCoordinateSystem(); }
109
110   //! Set system origin coordinate system to perform conversion into during read.
111   void SetSystemCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
112
113   //! Set system origin coordinate system to perform conversion into during read.
114   void SetSystemCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); }
115
116   //! Return the length unit to convert from while reading the file, defined as scale factor for m (meters).
117   //! Can be undefined (-1.0) if file format is unitless.
118   Standard_Real FileLengthUnit() const { return myCoordSysConverter.InputLengthUnit(); }
119
120   //! Set (override) file length units to convert from while reading the file, defined as scale factor for m (meters).
121   void SetFileLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetInputLengthUnit (theUnits); }
122
123   //! Return TRUE if file origin coordinate system has been defined.
124   Standard_Boolean HasFileCoordinateSystem() const { return myCoordSysConverter.HasInputCoordinateSystem(); }
125
126   //! Return file origin coordinate system; can be UNDEFINED, which means no conversion will be done.
127   const gp_Ax3& FileCoordinateSystem() const { return myCoordSysConverter.InputCoordinateSystem(); }
128
129   //! Set (override) file origin coordinate system to perform conversion during read.
130   void SetFileCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
131
132   //! Set (override) file origin coordinate system to perform conversion during read.
133   void SetFileCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); }
134
135 public:
136
137   //! Read the data from specified file.
138   //! The Document instance should be set beforehand.
139   bool Perform (const TCollection_AsciiString& theFile,
140                 const Handle(Message_ProgressIndicator)& theProgress)
141   {
142     return perform (theFile, theProgress, Standard_False);
143   }
144
145   //! Return extended status flags.
146   //! @sa RWMesh_CafReaderStatusEx enumeration.
147   Standard_Integer ExtraStatus() const { return myExtraStatus; }
148
149 public:
150
151   //! Return result as a single shape.
152   Standard_EXPORT TopoDS_Shape SingleShape() const;
153
154   //! Return the list of complementary files - external references (textures, data, etc.).
155   const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const { return myExternalFiles; }
156
157   //! Return metadata map.
158   const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; }
159
160   //! Read the header data from specified file without reading entire model.
161   //! The main purpose is collecting metadata and external references - for copying model into a new location, for example.
162   //! Can be NOT implemented (unsupported by format / reader).
163   Standard_Boolean ProbeHeader (const TCollection_AsciiString& theFile,
164                                 const Handle(Message_ProgressIndicator)& theProgress = Handle(Message_ProgressIndicator)())
165   {
166     return perform (theFile, theProgress, Standard_True);
167   }
168
169 protected:
170
171   //! Read the data from specified file.
172   //! Default implementation calls performMesh() and fills XDE document from collected shapes.
173   //! @param theFile    file to read
174   //! @param optional   progress indicator
175   //! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read
176   virtual Standard_Boolean perform (const TCollection_AsciiString& theFile,
177                                     const Handle(Message_ProgressIndicator)& theProgress,
178                                     const Standard_Boolean theToProbe);
179
180   //! Read the mesh from specified file - interface to be implemented by sub-classes.
181   virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
182                                         const Handle(Message_ProgressIndicator)& theProgress,
183                                         const Standard_Boolean theToProbe) = 0;
184
185 //! @name tools for filling XDE document
186 protected:
187
188   //! Append new shape into the document (recursively).
189   Standard_EXPORT Standard_Boolean addShapeIntoDoc (const TopoDS_Shape& theShape,
190                                                     const TDF_Label& theLabel,
191                                                     const TCollection_AsciiString& theParentName);
192
193   //! Generate names for root labels starting from specified index.
194   Standard_EXPORT void generateNames (const TCollection_AsciiString& theFile,
195                                       const Standard_Integer theRootLower,
196                                       const Standard_Boolean theWithSubLabels);
197
198   //! Return shape type as string.
199   //! @sa TopAbs::ShapeTypeToString()
200   static TCollection_AsciiString shapeTypeToString (TopAbs_ShapeEnum theType)
201   {
202     TCollection_AsciiString aString = TopAbs::ShapeTypeToString (theType);
203     aString.Capitalize();
204     return aString;
205   }
206
207 protected:
208
209   Handle(TDocStd_Document)  myXdeDoc;            //!< target document
210
211   TColStd_IndexedDataMapOfStringString
212                             myMetadata;          //!< metadata map
213   NCollection_IndexedMap<TCollection_AsciiString>
214                             myExternalFiles;     //!< the list of complementary files - external references (textures, data, etc.)
215   TCollection_AsciiString   myRootPrefix;        //!< root folder for generating root labels names
216   TopTools_SequenceOfShape  myRootShapes;        //!< sequence of result root shapes
217   RWMesh_NodeAttributeMap   myAttribMap;         //!< map of per-shape attributes
218
219   RWMesh_CoordinateSystemConverter
220                             myCoordSysConverter; //!< coordinate system converter
221   Standard_Boolean          myToFillDoc;         //!< fill document from shape sequence
222   Standard_Boolean          myToFillIncomplete;  //!< fill the document with partially retrieved data even if reader has failed with error
223   Standard_Integer          myMemoryLimitMiB;    //!< memory usage limit
224   Standard_Integer          myExtraStatus;       //!< extra status bitmask
225
226 };
227
228 #endif // _RWMesh_CafReader_HeaderFile