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 | |
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; |
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. |
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 |
82c59511 |
190 | Standard_EXPORT virtual Standard_Boolean perform (const TCollection_AsciiString& theFile, |
191 | const Handle(Message_ProgressIndicator)& theProgress, |
192 | const Standard_Boolean theToProbe); |
fc552d84 |
193 | |
194 | //! Read the mesh from specified file - interface to be implemented by sub-classes. |
82c59511 |
195 | Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile, |
196 | const Handle(Message_ProgressIndicator)& theProgress, |
197 | const Standard_Boolean theToProbe) = 0; |
fc552d84 |
198 | |
199 | //! @name tools for filling XDE document |
200 | protected: |
201 | |
82c59511 |
202 | //! Fill document with new root shapes. |
203 | Standard_EXPORT void fillDocument(); |
204 | |
fc552d84 |
205 | //! Append new shape into the document (recursively). |
5a8d30b8 |
206 | Standard_EXPORT Standard_Boolean addShapeIntoDoc (CafDocumentTools& theTools, |
207 | const TopoDS_Shape& theShape, |
fc552d84 |
208 | const TDF_Label& theLabel, |
209 | const TCollection_AsciiString& theParentName); |
210 | |
5a8d30b8 |
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 | |
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 |