0029303: Data Exchange - add RWObj_CafWriter tool for wavefront OBJ file
[occt.git] / src / RWMesh / RWMesh_FaceIterator.hxx
1 // Copyright (c) 2017-2019 OPEN CASCADE SAS
2 //
3 // This file is part of Open CASCADE Technology software library.
4 //
5 // This library is free software; you can redistribute it and/or modify it under
6 // the terms of the GNU Lesser General Public License version 2.1 as published
7 // by the Free Software Foundation, with special exception defined in the file
8 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9 // distribution for complete text of the license and disclaimer of any warranty.
10 //
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
13
14 #ifndef _RWMesh_FaceIterator_HeaderFile
15 #define _RWMesh_FaceIterator_HeaderFile
16
17 #include <BRepLProp_SLProps.hxx>
18 #include <gp_Trsf.hxx>
19 #include <NCollection_DataMap.hxx>
20 #include <Poly_Array1OfTriangle.hxx>
21 #include <Poly_Triangulation.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <TopoDS_Face.hxx>
24 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
25 #include <XCAFPrs_Style.hxx>
26
27 #include <algorithm>
28
29 class TDF_Label;
30
31 //! Auxiliary class to iterate through triangulated faces.
32 class RWMesh_FaceIterator
33 {
34 public:
35
36   //! Main constructor.
37   Standard_EXPORT RWMesh_FaceIterator (const TDF_Label&       theLabel,
38                                        const TopLoc_Location& theLocation,
39                                        const Standard_Boolean theToMapColors = false,
40                                        const XCAFPrs_Style&   theStyle = XCAFPrs_Style());
41
42   //! Return true if iterator points to the valid triangulation.
43   bool More() const { return !myPolyTriang.IsNull(); }
44
45   //! Find next value.
46   Standard_EXPORT void Next();
47
48   //! Return current face.
49   const TopoDS_Face& Face() const { return myFace; }
50
51   //! Return current face triangulation.
52   const Handle(Poly_Triangulation)& Triangulation() const { return myPolyTriang; }
53
54   //! Return true if mesh data is defined.
55   bool IsEmptyMesh() const
56   {
57     return myPolyTriang.IsNull()
58        || (myPolyTriang->NbNodes() < 1 && myPolyTriang->NbTriangles() < 1);
59   }
60
61 public:
62
63   //! Return face material.
64   const XCAFPrs_Style& FaceStyle() const { return myFaceStyle; }
65
66   //! Return TRUE if face color is set.
67   bool HasFaceColor() const { return myHasFaceColor; }
68
69   //! Return face color.
70   const Quantity_ColorRGBA& FaceColor() const { return myFaceColor; }
71
72 public:
73
74   //! Return number of elements of specific type for the current face.
75   Standard_Integer NbTriangles() const { return myPolyTriang->NbTriangles(); }
76
77   //! Lower element index in current triangulation.
78   Standard_Integer ElemLower() const { return 1; }
79
80   //! Upper element index in current triangulation.
81   Standard_Integer ElemUpper() const { return myPolyTriang->NbTriangles(); }
82
83   //! Return triangle with specified index with applied Face orientation.
84   Poly_Triangle TriangleOriented (Standard_Integer theElemIndex) const
85   {
86     Poly_Triangle aTri = triangle (theElemIndex);
87     if ((myFace.Orientation() == TopAbs_REVERSED) ^ myIsMirrored)
88     {
89       return Poly_Triangle (aTri.Value (1), aTri.Value (3), aTri.Value (2));
90     }
91     return aTri;
92   }
93
94 public:
95
96   //! Return true if triangulation has defined normals.
97   bool HasNormals() const { return myHasNormals; }
98
99   //! Return true if triangulation has defined normals.
100   bool HasTexCoords() const { return !myPolyTriang.IsNull() && myPolyTriang->HasUVNodes(); }
101
102   //! Return normal at specified node index with face transformation applied and face orientation applied.
103   gp_Dir NormalTransformed (Standard_Integer theNode) const
104   {
105     gp_Dir aNorm = normal (theNode);
106     if (myTrsf.Form() != gp_Identity)
107     {
108       aNorm.Transform (myTrsf);
109     }
110     if (myFace.Orientation() == TopAbs_REVERSED)
111     {
112       aNorm.Reverse();
113     }
114     return aNorm;
115   }
116
117   //! Return number of nodes for the current face.
118   Standard_Integer NbNodes() const
119   {
120     return !myPolyTriang.IsNull()
121           ? myPolyTriang->NbNodes()
122           : 0;
123   }
124
125   //! Lower node index in current triangulation.
126   Standard_Integer NodeLower() const { return 1; }
127
128   //! Upper node index in current triangulation.
129   Standard_Integer NodeUpper() const { return myPolyTriang->NbNodes(); }
130
131   //! Return the node with specified index with applied transformation.
132   gp_Pnt NodeTransformed (const Standard_Integer theNode) const
133   {
134     gp_Pnt aNode = node (theNode);
135     aNode.Transform (myTrsf);
136     return aNode;
137   }
138
139   //! Return texture coordinates for the node.
140   gp_Pnt2d NodeTexCoord (const Standard_Integer theNode) const
141   {
142     return myPolyTriang->HasUVNodes() ? myPolyTriang->UVNode (theNode) : gp_Pnt2d();
143   }
144
145 public:
146
147   //! Return the node with specified index with applied transformation.
148   gp_Pnt node (const Standard_Integer theNode) const { return myPolyTriang->Node (theNode); }
149
150   //! Return normal at specified node index without face transformation applied.
151   Standard_EXPORT gp_Dir normal (Standard_Integer theNode) const;
152
153   //! Return triangle with specified index.
154   Poly_Triangle triangle (Standard_Integer theElemIndex) const { return myPolyTriang->Triangle (theElemIndex); }
155
156 private:
157
158   //! Dispatch face styles.
159   void dispatchStyles (const TDF_Label&       theLabel,
160                        const TopLoc_Location& theLocation,
161                        const XCAFPrs_Style&   theStyle);
162
163   //! Reset information for current face.
164   void resetFace()
165   {
166     myPolyTriang.Nullify();
167     myFace.Nullify();
168     myHasNormals = false;
169     myHasFaceColor = false;
170     myFaceColor = Quantity_ColorRGBA();
171     myFaceStyle = XCAFPrs_Style();
172   }
173
174   //! Initialize face properties.
175   void initFace();
176
177 private:
178
179   NCollection_DataMap<TopoDS_Shape, XCAFPrs_Style, TopTools_ShapeMapHasher>
180                                   myStyles;       //!< Face -> Style map
181   XCAFPrs_Style                   myDefStyle;     //!< default style for faces without dedicated style
182   Standard_Boolean                myToMapColors;  //!< flag to dispatch styles
183
184   TopExp_Explorer                 myFaceIter;     //!< face explorer
185   TopoDS_Face                     myFace;         //!< current face
186   Handle(Poly_Triangulation)      myPolyTriang;   //!< triangulation of current face
187   TopLoc_Location                 myFaceLocation; //!< current face location
188   mutable BRepLProp_SLProps       mySLTool;       //!< auxiliary tool for fetching normals from surface
189   BRepAdaptor_Surface             myFaceAdaptor;  //!< surface adaptor for fetching normals from surface
190   Standard_Boolean                myHasNormals;   //!< flag indicating that current face has normals
191   gp_Trsf                         myTrsf;         //!< current face transformation
192   Standard_Boolean                myIsMirrored;   //!< flag indicating that face triangles should be mirrored
193   XCAFPrs_Style                   myFaceStyle;    //!< current face style
194   Quantity_ColorRGBA              myFaceColor;    //!< current face color
195   Standard_Boolean                myHasFaceColor; //!< flag indicating that current face has assigned color
196
197 };
198
199 #endif // _RWMesh_FaceIterator_HeaderFile