a7f6d58ae5396c87efae9ff40ca48210f35ee141
[occt.git] / src / RWMesh / RWMesh_FaceIterator.cxx
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 #include <RWMesh_FaceIterator.hxx>
15
16 #include <BRepAdaptor_Surface.hxx>
17 #include <BRep_Tool.hxx>
18 #include <TopExp.hxx>
19 #include <TopoDS.hxx>
20 #include <XCAFDoc_ShapeTool.hxx>
21 #include <XCAFPrs.hxx>
22
23 // =======================================================================
24 // function : RWMesh_FaceIterator
25 // purpose  :
26 // =======================================================================
27 RWMesh_FaceIterator::RWMesh_FaceIterator (const TDF_Label&       theLabel,
28                                           const TopLoc_Location& theLocation,
29                                           const Standard_Boolean theToMapColors,
30                                           const XCAFPrs_Style&   theStyle)
31 : myDefStyle (theStyle),
32   myToMapColors (theToMapColors),
33   mySLTool  (1, 1e-12),
34   myHasNormals (false),
35   myIsMirrored (false),
36   myHasFaceColor (false)
37 {
38   TopoDS_Shape aShape;
39   if (!XCAFDoc_ShapeTool::GetShape (theLabel, aShape)
40    ||  aShape.IsNull())
41   {
42     return;
43   }
44
45   aShape.Location (theLocation, false);
46   myFaceIter.Init (aShape, TopAbs_FACE);
47
48   if (theToMapColors)
49   {
50     dispatchStyles (theLabel, theLocation, theStyle);
51     myStyles.Bind (aShape, theStyle);
52   }
53
54   Next();
55 }
56
57 // =======================================================================
58 // function : RWMesh_FaceIterator
59 // purpose  :
60 // =======================================================================
61 RWMesh_FaceIterator::RWMesh_FaceIterator (const TopoDS_Shape&  theShape,
62                                           const XCAFPrs_Style& theStyle)
63 : myDefStyle (theStyle),
64   myToMapColors (true),
65   mySLTool  (1, 1e-12),
66   myHasNormals (false),
67   myIsMirrored (false),
68   myHasFaceColor (false)
69 {
70   if (theShape.IsNull())
71   {
72     return;
73   }
74
75   myFaceIter.Init (theShape, TopAbs_FACE);
76   Next();
77 }
78
79 // =======================================================================
80 // function : dispatchStyles
81 // purpose  :
82 // =======================================================================
83 void RWMesh_FaceIterator::dispatchStyles (const TDF_Label&       theLabel,
84                                           const TopLoc_Location& theLocation,
85                                           const XCAFPrs_Style&   theStyle)
86 {
87   TopLoc_Location aDummyLoc;
88   XCAFPrs_IndexedDataMapOfShapeStyle aStyles;
89   XCAFPrs::CollectStyleSettings (theLabel, aDummyLoc, aStyles);
90
91   Standard_Integer aNbTypes[TopAbs_SHAPE] = {};
92   for (Standard_Integer aTypeIter = TopAbs_FACE; aTypeIter >= TopAbs_COMPOUND; --aTypeIter)
93   {
94     if (aTypeIter != TopAbs_FACE
95      && aNbTypes[aTypeIter] == 0)
96     {
97       continue;
98     }
99
100     for (XCAFPrs_IndexedDataMapOfShapeStyle::Iterator aStyleIter (aStyles); aStyleIter.More(); aStyleIter.Next())
101     {
102       const TopoDS_Shape&    aKeyShape     = aStyleIter.Key();
103       const TopAbs_ShapeEnum aKeyShapeType = aKeyShape.ShapeType();
104       if (aTypeIter == TopAbs_FACE)
105       {
106         ++aNbTypes[aKeyShapeType];
107       }
108       if (aTypeIter != aKeyShapeType)
109       {
110         continue;
111       }
112
113       XCAFPrs_Style aCafStyle = aStyleIter.Value();
114       if (!aCafStyle.IsSetColorCurv()
115          && theStyle.IsSetColorCurv())
116       {
117         aCafStyle.SetColorCurv (theStyle.GetColorCurv());
118       }
119       if (!aCafStyle.IsSetColorSurf()
120          && theStyle.IsSetColorSurf())
121       {
122         aCafStyle.SetColorSurf (theStyle.GetColorSurfRGBA());
123       }
124       if (aCafStyle.Material().IsNull()
125        && !theStyle.Material().IsNull())
126       {
127         aCafStyle.SetMaterial (theStyle.Material());
128       }
129
130       TopoDS_Shape aKeyShapeLocated = aKeyShape.Located (theLocation);
131       if (aKeyShapeType == TopAbs_FACE)
132       {
133         myStyles.Bind (aKeyShapeLocated, aCafStyle);
134       }
135       else
136       {
137         for (TopExp_Explorer aFaceIter (aKeyShapeLocated, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
138         {
139           if (!myStyles.IsBound (aFaceIter.Current()))
140           {
141             myStyles.Bind (aFaceIter.Current(), aCafStyle);
142           }
143         }
144       }
145     }
146   }
147 }
148
149 // =======================================================================
150 // function : normal
151 // purpose  :
152 // =======================================================================
153 gp_Dir RWMesh_FaceIterator::normal (Standard_Integer theNode) const
154 {
155   gp_Dir aNormal (gp::DZ());
156   if (myPolyTriang->HasNormals())
157   {
158     Graphic3d_Vec3 aNormVec3;
159     myPolyTriang->Normal (theNode, aNormVec3);
160     if (aNormVec3.Modulus() != 0.0f)
161     {
162       aNormal.SetCoord (aNormVec3.x(), aNormVec3.y(), aNormVec3.z());
163     }
164   }
165   else if (myHasNormals
166         && myPolyTriang->HasUVNodes())
167   {
168     const gp_XY anUV = myPolyTriang->UVNode (theNode).XY();
169     mySLTool.SetParameters (anUV.X(), anUV.Y());
170     if (mySLTool.IsNormalDefined())
171     {
172       aNormal = mySLTool.Normal();
173     }
174   }
175   return aNormal;
176 }
177
178 // =======================================================================
179 // function : Next
180 // purpose  :
181 // =======================================================================
182 void RWMesh_FaceIterator::Next()
183 {
184   for (; myFaceIter.More(); myFaceIter.Next())
185   {
186     myFace       = TopoDS::Face (myFaceIter.Current());
187     myPolyTriang = BRep_Tool::Triangulation (myFace, myFaceLocation);
188     myTrsf       = myFaceLocation.Transformation();
189     if (myPolyTriang.IsNull()
190      || myPolyTriang->NbTriangles() == 0)
191     {
192       resetFace();
193       continue;
194     }
195
196     initFace();
197     myFaceIter.Next();
198     return;
199   }
200
201   resetFace();
202 }
203
204 // =======================================================================
205 // function : initFace
206 // purpose  :
207 // =======================================================================
208 void RWMesh_FaceIterator::initFace()
209 {
210   myHasNormals   = false;
211   myHasFaceColor = false;
212   myIsMirrored   = myTrsf.VectorialPart().Determinant() < 0.0;
213   if (myPolyTriang->HasNormals())
214   {
215     myHasNormals = true;
216   }
217   if (myPolyTriang->HasUVNodes() && !myHasNormals)
218   {
219     TopoDS_Face aFaceFwd = TopoDS::Face (myFace.Oriented (TopAbs_FORWARD));
220     aFaceFwd.Location (TopLoc_Location());
221     TopLoc_Location aLoc;
222     if (!BRep_Tool::Surface (aFaceFwd, aLoc).IsNull())
223     {
224       myFaceAdaptor.Initialize (aFaceFwd, false);
225       mySLTool.SetSurface (myFaceAdaptor);
226       myHasNormals = true;
227     }
228   }
229   if (!myToMapColors)
230   {
231     return;
232   }
233
234   if (!myStyles.Find (myFace, myFaceStyle))
235   {
236     myFaceStyle = myDefStyle;
237   }
238
239   if (!myFaceStyle.Material().IsNull())
240   {
241     myHasFaceColor = true;
242     myFaceColor = myFaceStyle.Material()->BaseColor();
243   }
244   else if (myFaceStyle.IsSetColorSurf())
245   {
246     myHasFaceColor = true;
247     myFaceColor = myFaceStyle.GetColorSurfRGBA();
248   }
249 }