Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-15 09:16:53

0001 // Author: Kirill Gavrilov
0002 // Copyright (c) 2016-2019 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _RWMesh_CafReader_HeaderFile
0016 #define _RWMesh_CafReader_HeaderFile
0017 
0018 #include <Message_ProgressRange.hxx>
0019 #include <OSD_OpenFile.hxx>
0020 #include <RWMesh_CoordinateSystemConverter.hxx>
0021 #include <RWMesh_NodeAttributes.hxx>
0022 #include <TCollection_AsciiString.hxx>
0023 #include <NCollection_IndexedDataMap.hxx>
0024 #include <TDF_Label.hxx>
0025 #include <TopoDS_Shape.hxx>
0026 #include <NCollection_Sequence.hxx>
0027 
0028 class TDocStd_Document;
0029 class XCAFDoc_ShapeTool;
0030 class XCAFDoc_ColorTool;
0031 class XCAFDoc_VisMaterialTool;
0032 
0033 //! Extended status bits.
0034 enum RWMesh_CafReaderStatusEx
0035 {
0036   RWMesh_CafReaderStatusEx_NONE = 0, //!< empty status
0037   RWMesh_CafReaderStatusEx_Partial =
0038     0x01, //!< partial read (due to unexpected EOF, syntax error, memory limit)
0039 };
0040 
0041 //! The general interface for importing mesh data into XDE document.
0042 //!
0043 //! The tool implements auxiliary structures for creating an XDE document in two steps:
0044 //! 1) Creating TopoDS_Shape hierarchy (myRootShapes)
0045 //!    and Shape attributes (myAttribMap) separately within performMesh().
0046 //!    Attributes include names and styles.
0047 //! 2) Filling XDE document from these auxiliary structures.
0048 //!    Named elements are expanded within document structure, while Compounds having no named
0049 //!    children will remain collapsed. In addition, unnamed nodes can be filled with generated names
0050 //!    like "Face", "Compound" via generateNames() method, and the very root unnamed node can be
0051 //!    filled from file name like "MyModel.obj".
0052 class RWMesh_CafReader : public Standard_Transient
0053 {
0054   DEFINE_STANDARD_RTTIEXT(RWMesh_CafReader, Standard_Transient)
0055 public:
0056   //! Structure holding tools for filling the document.
0057   struct CafDocumentTools
0058   {
0059     occ::handle<XCAFDoc_ShapeTool>                                        ShapeTool;
0060     occ::handle<XCAFDoc_ColorTool>                                        ColorTool;
0061     occ::handle<XCAFDoc_VisMaterialTool>                                  VisMaterialTool;
0062     NCollection_DataMap<TopoDS_Shape, TDF_Label, TopTools_ShapeMapHasher> ComponentMap;
0063     NCollection_DataMap<TopoDS_Shape, TDF_Label, TopTools_ShapeMapHasher> OriginalShapeMap;
0064   };
0065 
0066 public:
0067   //! Empty constructor.
0068   Standard_EXPORT RWMesh_CafReader();
0069 
0070   //! Destructor.
0071   Standard_EXPORT ~RWMesh_CafReader() override;
0072 
0073   //! Return target document.
0074   const occ::handle<TDocStd_Document>& Document() const { return myXdeDoc; }
0075 
0076   //! Set target document.
0077   //! Set system length unit according to the units of the document
0078   Standard_EXPORT void SetDocument(const occ::handle<TDocStd_Document>& theDoc);
0079 
0080   //! Return prefix for generating root labels names.
0081   const TCollection_AsciiString& RootPrefix() const { return myRootPrefix; }
0082 
0083   //! Set prefix for generating root labels names
0084   void SetRootPrefix(const TCollection_AsciiString& theRootPrefix) { myRootPrefix = theRootPrefix; }
0085 
0086   //! Flag indicating if partially read file content should be put into the XDE document, TRUE by
0087   //! default.
0088   //!
0089   //! Partial read means unexpected end of file, critical parsing syntax errors in the middle of
0090   //! file, or reached memory limit indicated by performMesh() returning FALSE. Partial read allows
0091   //! importing a model even in case of formal reading failure, so that it will be up to user to
0092   //! decide if processed data has any value.
0093   //!
0094   //! In case of partial read (performMesh() returns FALSE, but there are some data that could be
0095   //! put into document), Perform() will return TRUE and result flag will have failure bit set.
0096   //! @sa MemoryLimitMiB(), ExtraStatus().
0097   bool ToFillIncompleteDocument() const { return myToFillIncomplete; }
0098 
0099   //! Set flag allowing partially read file content to be put into the XDE document.
0100   void SetFillIncompleteDocument(bool theToFillIncomplete)
0101   {
0102     myToFillIncomplete = theToFillIncomplete;
0103   }
0104 
0105   //! Return memory usage limit in MiB, -1 by default which means no limit.
0106   int MemoryLimitMiB() const { return myMemoryLimitMiB; }
0107 
0108   //! Set memory usage limit in MiB; can be ignored by reader implementation!
0109   void SetMemoryLimitMiB(int theLimitMiB) { myMemoryLimitMiB = theLimitMiB; }
0110 
0111 public:
0112   //! Return coordinate system converter.
0113   const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const
0114   {
0115     return myCoordSysConverter;
0116   }
0117 
0118   //! Set coordinate system converter.
0119   void SetCoordinateSystemConverter(const RWMesh_CoordinateSystemConverter& theConverter)
0120   {
0121     myCoordSysConverter = theConverter;
0122   }
0123 
0124   //! Return the length unit to convert into while reading the file, defined as scale factor for m
0125   //! (meters); -1.0 by default, which means that NO conversion will be applied.
0126   double SystemLengthUnit() const { return myCoordSysConverter.OutputLengthUnit(); }
0127 
0128   //! Set system length units to convert into while reading the file, defined as scale factor for m
0129   //! (meters).
0130   void SetSystemLengthUnit(double theUnits) { myCoordSysConverter.SetOutputLengthUnit(theUnits); }
0131 
0132   //! Return TRUE if system coordinate system has been defined; FALSE by default.
0133   bool HasSystemCoordinateSystem() const { return myCoordSysConverter.HasOutputCoordinateSystem(); }
0134 
0135   //! Return system coordinate system; UNDEFINED by default, which means that no conversion will be
0136   //! done.
0137   const gp_Ax3& SystemCoordinateSystem() const
0138   {
0139     return myCoordSysConverter.OutputCoordinateSystem();
0140   }
0141 
0142   //! Set system origin coordinate system to perform conversion into during read.
0143   void SetSystemCoordinateSystem(const gp_Ax3& theCS)
0144   {
0145     myCoordSysConverter.SetOutputCoordinateSystem(theCS);
0146   }
0147 
0148   //! Set system origin coordinate system to perform conversion into during read.
0149   void SetSystemCoordinateSystem(RWMesh_CoordinateSystem theCS)
0150   {
0151     myCoordSysConverter.SetOutputCoordinateSystem(theCS);
0152   }
0153 
0154   //! Return the length unit to convert from while reading the file, defined as scale factor for m
0155   //! (meters). Can be undefined (-1.0) if file format is unitless.
0156   double FileLengthUnit() const { return myCoordSysConverter.InputLengthUnit(); }
0157 
0158   //! Set (override) file length units to convert from while reading the file, defined as scale
0159   //! factor for m (meters).
0160   void SetFileLengthUnit(double theUnits) { myCoordSysConverter.SetInputLengthUnit(theUnits); }
0161 
0162   //! Return TRUE if file origin coordinate system has been defined.
0163   bool HasFileCoordinateSystem() const { return myCoordSysConverter.HasInputCoordinateSystem(); }
0164 
0165   //! Return file origin coordinate system; can be UNDEFINED, which means no conversion will be
0166   //! done.
0167   const gp_Ax3& FileCoordinateSystem() const { return myCoordSysConverter.InputCoordinateSystem(); }
0168 
0169   //! Set (override) file origin coordinate system to perform conversion during read.
0170   void SetFileCoordinateSystem(const gp_Ax3& theCS)
0171   {
0172     myCoordSysConverter.SetInputCoordinateSystem(theCS);
0173   }
0174 
0175   //! Set (override) file origin coordinate system to perform conversion during read.
0176   void SetFileCoordinateSystem(RWMesh_CoordinateSystem theCS)
0177   {
0178     myCoordSysConverter.SetInputCoordinateSystem(theCS);
0179   }
0180 
0181 public:
0182   //! Open stream and pass it to Perform method.
0183   //! The Document instance should be set beforehand.
0184   bool Perform(const TCollection_AsciiString& theFile, const Message_ProgressRange& theProgress)
0185   {
0186     std::ifstream aStream;
0187     OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
0188     return Perform(aStream, theProgress, theFile);
0189   }
0190 
0191   //! Read the data from specified file.
0192   bool Perform(std::istream&                  theStream,
0193                const Message_ProgressRange&   theProgress,
0194                const TCollection_AsciiString& theFile = "")
0195   {
0196     return perform(theStream, theFile, theProgress, false);
0197   }
0198 
0199   //! Return extended status flags.
0200   //! @sa RWMesh_CafReaderStatusEx enumeration.
0201   int ExtraStatus() const { return myExtraStatus; }
0202 
0203 public:
0204   //! Return result as a single shape.
0205   Standard_EXPORT TopoDS_Shape SingleShape() const;
0206 
0207   //! Return the list of complementary files - external references (textures, data, etc.).
0208   const NCollection_IndexedMap<TCollection_AsciiString>& ExternalFiles() const
0209   {
0210     return myExternalFiles;
0211   }
0212 
0213   //! Return metadata map.
0214   const NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>& Metadata()
0215     const
0216   {
0217     return myMetadata;
0218   }
0219 
0220   //! Open stream and pass it to ProbeHeader method.
0221   bool ProbeHeader(const TCollection_AsciiString& theFile,
0222                    const Message_ProgressRange&   theProgress = Message_ProgressRange())
0223   {
0224     std::ifstream aStream;
0225     OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
0226     return ProbeHeader(aStream, theFile, theProgress);
0227   }
0228 
0229   //! Read the header data from specified file without reading entire model.
0230   //! The main purpose is collecting metadata and external references - for copying model into a new
0231   //! location, for example. Can be NOT implemented (unsupported by format / reader).
0232   bool ProbeHeader(std::istream&                  theStream,
0233                    const TCollection_AsciiString& theFile     = "",
0234                    const Message_ProgressRange&   theProgress = Message_ProgressRange())
0235   {
0236     return perform(theStream, theFile, theProgress, true);
0237   }
0238 
0239 protected:
0240   //! Open stream and pass it to Perform method.
0241   //! @param theFile    file to read
0242   //! @param optional   progress indicator
0243   //! @param theToProbe flag indicating that mesh data should be skipped and only basing information
0244   //! to be read
0245   Standard_EXPORT virtual bool perform(const TCollection_AsciiString& theFile,
0246                                        const Message_ProgressRange&   theProgress,
0247                                        const bool                     theToProbe);
0248 
0249   //! Read the data from specified file.
0250   //! Default implementation calls performMesh() and fills XDE document from collected shapes.
0251   //! @param theStream  input stream
0252   //! @param theFile    path of additional files
0253   //! @param optional   progress indicator
0254   //! @param theToProbe flag indicating that mesh data should be skipped and only basing information
0255   //! to be read
0256   Standard_EXPORT virtual bool perform(std::istream&                  theStream,
0257                                        const TCollection_AsciiString& theFile,
0258                                        const Message_ProgressRange&   theProgress,
0259                                        const bool                     theToProbe);
0260 
0261   //! Read the mesh from specified file
0262   Standard_EXPORT virtual bool performMesh(const TCollection_AsciiString& theFile,
0263                                            const Message_ProgressRange&   theProgress,
0264                                            const bool                     theToProbe)
0265   {
0266     std::ifstream aStream;
0267     OSD_OpenStream(aStream, theFile, std::ios_base::in | std::ios_base::binary);
0268     return performMesh(aStream, theFile, theProgress, theToProbe);
0269   }
0270 
0271   //! Read the mesh from specified file - interface to be implemented by sub-classes.
0272   Standard_EXPORT virtual bool performMesh(std::istream&                  theStream,
0273                                            const TCollection_AsciiString& theFile,
0274                                            const Message_ProgressRange&   theProgress,
0275                                            const bool                     theToProbe) = 0;
0276 
0277   //! @name tools for filling XDE document
0278 protected:
0279   //! Fill document with new root shapes.
0280   Standard_EXPORT virtual void fillDocument();
0281 
0282   //! Append new shape into the document (recursively).
0283   Standard_EXPORT bool addShapeIntoDoc(CafDocumentTools&              theTools,
0284                                        const TopoDS_Shape&            theShape,
0285                                        const TDF_Label&               theLabel,
0286                                        const TCollection_AsciiString& theParentName);
0287 
0288   //! Append new sub-shape into the document (recursively).
0289   Standard_EXPORT bool addSubShapeIntoDoc(CafDocumentTools&   theTools,
0290                                           const TopoDS_Shape& theShape,
0291                                           const TDF_Label&    theParentLabel);
0292 
0293   //! Put name attribute onto the label.
0294   Standard_EXPORT void setShapeName(const TDF_Label&               theLabel,
0295                                     const TopAbs_ShapeEnum         theShapeType,
0296                                     const TCollection_AsciiString& theName,
0297                                     const TDF_Label&               theParentLabel,
0298                                     const TCollection_AsciiString& theParentName);
0299 
0300   //! Put color and material attributes onto the label.
0301   Standard_EXPORT void setShapeStyle(const CafDocumentTools& theTools,
0302                                      const TDF_Label&        theLabel,
0303                                      const XCAFPrs_Style&    theStyle);
0304 
0305   //! Put name data (metadata) attribute onto the label.
0306   Standard_EXPORT void setShapeNamedData(const CafDocumentTools&                theTools,
0307                                          const TDF_Label&                       theLabel,
0308                                          const occ::handle<TDataStd_NamedData>& theNameData);
0309 
0310   //! Generate names for root labels starting from specified index.
0311   Standard_EXPORT void generateNames(const TCollection_AsciiString& theFile,
0312                                      const int                      theRootLower,
0313                                      const bool                     theWithSubLabels);
0314 
0315   //! Return shape type as string.
0316   //! @sa TopAbs::ShapeTypeToString()
0317   static TCollection_AsciiString shapeTypeToString(TopAbs_ShapeEnum theType)
0318   {
0319     TCollection_AsciiString aString = TopAbs::ShapeTypeToString(theType);
0320     aString.Capitalize();
0321     return aString;
0322   }
0323 
0324 protected:
0325   occ::handle<TDocStd_Document> myXdeDoc; //!< target document
0326 
0327   NCollection_IndexedDataMap<TCollection_AsciiString, TCollection_AsciiString>
0328     myMetadata; //!< metadata map
0329   NCollection_IndexedMap<TCollection_AsciiString>
0330     // clang-format off
0331                             myExternalFiles;     //!< the list of complementary files - external references (textures, data, etc.)
0332   TCollection_AsciiString   myRootPrefix;        //!< root folder for generating root labels names
0333   NCollection_Sequence<TopoDS_Shape>  myRootShapes;        //!< sequence of result root shapes
0334   NCollection_DataMap<TopoDS_Shape, RWMesh_NodeAttributes, TopTools_ShapeMapHasher>   myAttribMap;         //!< map of per-shape attributes
0335 
0336   RWMesh_CoordinateSystemConverter
0337                             myCoordSysConverter; //!< coordinate system converter
0338   bool          myToFillDoc;         //!< fill document from shape sequence
0339   bool          myToFillIncomplete;  //!< fill the document with partially retrieved data even if reader has failed with error
0340   // clang-format on
0341   int myMemoryLimitMiB; //!< memory usage limit
0342   int myExtraStatus;    //!< extra status bitmask
0343 };
0344 
0345 #endif // _RWMesh_CafReader_HeaderFile