fc552d84 |
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 | |
7e785937 |
18 | #include <Message_ProgressRange.hxx> |
fc552d84 |
19 | #include <NCollection_IndexedMap.hxx> |
20 | #include <RWMesh_CoordinateSystemConverter.hxx> |
21 | #include <RWMesh_NodeAttributes.hxx> |
22 | #include <TColStd_IndexedDataMapOfStringString.hxx> |
23 | #include <TDF_Label.hxx> |
24 | #include <TopTools_SequenceOfShape.hxx> |
25 | |
fc552d84 |
26 | class TDocStd_Document; |
5a8d30b8 |
27 | class XCAFDoc_ShapeTool; |
28 | class XCAFDoc_ColorTool; |
29 | class XCAFDoc_VisMaterialTool; |
fc552d84 |
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) |
5a8d30b8 |
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 | |
fc552d84 |
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. |
da80ff68 |
74 | //! Set system length unit according to the units of the document |
75 | Standard_EXPORT void SetDocument(const Handle(TDocStd_Document)& theDoc); |
fc552d84 |
76 | |
77 | //! Return prefix for generating root labels names. |
78 | const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; } |
79 | |
80 | //! Set prefix for generating root labels names |
81 | void SetRootPrefix (const TCollection_AsciiString& theRootPrefix) { myRootPrefix = theRootPrefix; } |
82 | |
83 | //! Flag indicating if partially read file content should be put into the XDE document, TRUE by default. |
84 | //! |
85 | //! Partial read means unexpected end of file, critical parsing syntax errors in the middle of file, or reached memory limit |
86 | //! indicated by performMesh() returning FALSE. |
87 | //! Partial read allows importing a model even in case of formal reading failure, |
88 | //! so that it will be up to user to decide if processed data has any value. |
89 | //! |
90 | //! In case of partial read (performMesh() returns FALSE, but there are some data that could be put into document), |
91 | //! Perform() will return TRUE and result flag will have failure bit set. |
92 | //! @sa MemoryLimitMiB(), ExtraStatus(). |
93 | Standard_Boolean ToFillIncompleteDocument() const { return myToFillIncomplete; } |
94 | |
95 | //! Set flag allowing partially read file content to be put into the XDE document. |
96 | void SetFillIncompleteDocument (Standard_Boolean theToFillIncomplete) { myToFillIncomplete = theToFillIncomplete; } |
97 | |
98 | //! Return memory usage limit in MiB, -1 by default which means no limit. |
99 | Standard_Integer MemoryLimitMiB() const { return myMemoryLimitMiB; } |
100 | |
101 | //! Set memory usage limit in MiB; can be ignored by reader implementation! |
102 | void SetMemoryLimitMiB (Standard_Integer theLimitMiB) { myMemoryLimitMiB = theLimitMiB; } |
103 | |
104 | public: |
105 | |
106 | //! Return coordinate system converter. |
107 | const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCoordSysConverter; } |
108 | |
109 | //! Set coordinate system converter. |
110 | void SetCoordinateSystemConverter (const RWMesh_CoordinateSystemConverter& theConverter) { myCoordSysConverter = theConverter; } |
111 | |
112 | //! Return the length unit to convert into while reading the file, defined as scale factor for m (meters); |
113 | //! -1.0 by default, which means that NO conversion will be applied. |
114 | Standard_Real SystemLengthUnit() const { return myCoordSysConverter.OutputLengthUnit(); } |
115 | |
116 | //! Set system length units to convert into while reading the file, defined as scale factor for m (meters). |
117 | void SetSystemLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetOutputLengthUnit (theUnits); } |
118 | |
119 | //! Return TRUE if system coordinate system has been defined; FALSE by default. |
120 | Standard_Boolean HasSystemCoordinateSystem() const { return myCoordSysConverter.HasOutputCoordinateSystem(); } |
121 | |
122 | //! Return system coordinate system; UNDEFINED by default, which means that no conversion will be done. |
123 | const gp_Ax3& SystemCoordinateSystem() const { return myCoordSysConverter.OutputCoordinateSystem(); } |
124 | |
125 | //! Set system origin coordinate system to perform conversion into during read. |
126 | void SetSystemCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); } |
127 | |
128 | //! Set system origin coordinate system to perform conversion into during read. |
129 | void SetSystemCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetOutputCoordinateSystem (theCS); } |
130 | |
131 | //! Return the length unit to convert from while reading the file, defined as scale factor for m (meters). |
132 | //! Can be undefined (-1.0) if file format is unitless. |
133 | Standard_Real FileLengthUnit() const { return myCoordSysConverter.InputLengthUnit(); } |
134 | |
135 | //! Set (override) file length units to convert from while reading the file, defined as scale factor for m (meters). |
136 | void SetFileLengthUnit (Standard_Real theUnits) { myCoordSysConverter.SetInputLengthUnit (theUnits); } |
137 | |
138 | //! Return TRUE if file origin coordinate system has been defined. |
139 | Standard_Boolean HasFileCoordinateSystem() const { return myCoordSysConverter.HasInputCoordinateSystem(); } |
140 | |
141 | //! Return file origin coordinate system; can be UNDEFINED, which means no conversion will be done. |
142 | const gp_Ax3& FileCoordinateSystem() const { return myCoordSysConverter.InputCoordinateSystem(); } |
143 | |
144 | //! Set (override) file origin coordinate system to perform conversion during read. |
145 | void SetFileCoordinateSystem (const gp_Ax3& theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); } |
146 | |
147 | //! Set (override) file origin coordinate system to perform conversion during read. |
148 | void SetFileCoordinateSystem (RWMesh_CoordinateSystem theCS) { myCoordSysConverter.SetInputCoordinateSystem (theCS); } |
149 | |
150 | public: |
151 | |
152 | //! Read the data from specified file. |
153 | //! The Document instance should be set beforehand. |
154 | bool Perform (const TCollection_AsciiString& theFile, |
7e785937 |
155 | const Message_ProgressRange& theProgress) |
fc552d84 |
156 | { |
157 | return perform (theFile, theProgress, Standard_False); |
158 | } |
159 | |
160 | //! Return extended status flags. |
161 | //! @sa RWMesh_CafReaderStatusEx enumeration. |
162 | Standard_Integer ExtraStatus() const { return myExtraStatus; } |
163 | |
164 | public: |
165 | |
166 | //! Return result as a single shape. |
167 | Standard_EXPORT TopoDS_Shape SingleShape() const; |
168 | |
169 | //! Return the list of complementary files - external references (textures, data, etc.). |
170 | const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const { return myExternalFiles; } |
171 | |
172 | //! Return metadata map. |
173 | const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; } |
174 | |
175 | //! Read the header data from specified file without reading entire model. |
176 | //! The main purpose is collecting metadata and external references - for copying model into a new location, for example. |
177 | //! Can be NOT implemented (unsupported by format / reader). |
178 | Standard_Boolean ProbeHeader (const TCollection_AsciiString& theFile, |
7e785937 |
179 | const Message_ProgressRange& theProgress = Message_ProgressRange()) |
fc552d84 |
180 | { |
181 | return perform (theFile, theProgress, Standard_True); |
182 | } |
183 | |
184 | protected: |
185 | |
186 | //! Read the data from specified file. |
187 | //! Default implementation calls performMesh() and fills XDE document from collected shapes. |
188 | //! @param theFile file to read |
189 | //! @param optional progress indicator |
190 | //! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read |
82c59511 |
191 | Standard_EXPORT virtual Standard_Boolean perform (const TCollection_AsciiString& theFile, |
7e785937 |
192 | const Message_ProgressRange& theProgress, |
82c59511 |
193 | const Standard_Boolean theToProbe); |
fc552d84 |
194 | |
195 | //! Read the mesh from specified file - interface to be implemented by sub-classes. |
82c59511 |
196 | Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile, |
7e785937 |
197 | const Message_ProgressRange& theProgress, |
82c59511 |
198 | const Standard_Boolean theToProbe) = 0; |
fc552d84 |
199 | |
200 | //! @name tools for filling XDE document |
201 | protected: |
202 | |
82c59511 |
203 | //! Fill document with new root shapes. |
596e7839 |
204 | Standard_EXPORT virtual void fillDocument(); |
82c59511 |
205 | |
fc552d84 |
206 | //! Append new shape into the document (recursively). |
5a8d30b8 |
207 | Standard_EXPORT Standard_Boolean addShapeIntoDoc (CafDocumentTools& theTools, |
208 | const TopoDS_Shape& theShape, |
fc552d84 |
209 | const TDF_Label& theLabel, |
210 | const TCollection_AsciiString& theParentName); |
211 | |
5a8d30b8 |
212 | //! Append new sub-shape into the document (recursively). |
213 | Standard_EXPORT Standard_Boolean addSubShapeIntoDoc (CafDocumentTools& theTools, |
214 | const TopoDS_Shape& theShape, |
596e7839 |
215 | const TDF_Label& theParentLabel); |
5a8d30b8 |
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 | |
fc552d84 |
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 |