0026106: BRepMesh - revision of data model
[occt.git] / src / BRepMesh / BRepMesh_FaceAttribute.cxx
1 // Created by: Ekaterina SMIRNOVA
2 // Copyright (c) 2008-2014 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 #include <BRepMesh_FaceAttribute.hxx>
16 #include <TopoDS_Vertex.hxx>
17 #include <BRepAdaptor_HSurface.hxx>
18 #include <BRepMesh_ShapeTool.hxx>
19 #include <BRepMesh_Classifier.hxx>
20 #include <BRepTools.hxx>
21 #include <TopExp_Explorer.hxx>
22 #include <TopoDS_Wire.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS.hxx>
25 #include <TopoDS_Iterator.hxx>
26 #include <BRep_Tool.hxx>
27
28 IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FaceAttribute,Standard_Transient)
29
30 //=======================================================================
31 //function : Constructor
32 //purpose  : 
33 //=======================================================================
34 BRepMesh_FaceAttribute::BRepMesh_FaceAttribute()
35   : myDefFace         (0.),
36     myUMin            (0.),
37     myUMax            (0.),
38     myVMin            (0.),
39     myVMax            (0.),
40     myDeltaX          (1.),
41     myDeltaY          (1.),
42     myMinStep         (-1.),
43     myStatus          (BRepMesh_NoError),
44     myAdaptiveMin     (Standard_False)
45 {
46   init();
47 }
48
49 //=======================================================================
50 //function : Constructor
51 //purpose  : 
52 //=======================================================================
53 BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
54   const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
55   const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints)
56   : myDefFace         (0.),
57     myUMin            (0.),
58     myUMax            (0.),
59     myVMin            (0.),
60     myVMax            (0.),
61     myDeltaX          (1.),
62     myDeltaY          (1.),
63     myMinStep         (-1.),
64     myStatus          (BRepMesh_NoError),
65     myAdaptiveMin     (Standard_False),
66     myBoundaryVertices(theBoundaryVertices),
67     myBoundaryPoints  (theBoundaryPoints)
68 {
69 }
70
71 //=======================================================================
72 //function : Constructor
73 //purpose  : 
74 //=======================================================================
75 BRepMesh_FaceAttribute::BRepMesh_FaceAttribute(
76   const TopoDS_Face&                    theFace,
77   const BRepMesh::HDMapOfVertexInteger& theBoundaryVertices,
78   const BRepMesh::HDMapOfIntegerPnt&    theBoundaryPoints,
79   const Standard_Boolean                theAdaptiveMin)
80   : myDefFace         (0.),
81     myUMin            (0.),
82     myUMax            (0.),
83     myVMin            (0.),
84     myVMax            (0.),
85     myDeltaX          (1.),
86     myDeltaY          (1.),
87     myMinStep         (-1.),
88     myStatus          (BRepMesh_NoError),
89     myAdaptiveMin     (theAdaptiveMin),
90     myBoundaryVertices(theBoundaryVertices),
91     myBoundaryPoints  (theBoundaryPoints),
92     myFace            (theFace)
93 {
94   init();
95 }
96
97 //=======================================================================
98 //function : Destructor
99 //purpose  : 
100 //=======================================================================
101 BRepMesh_FaceAttribute::~BRepMesh_FaceAttribute()
102 {
103 }
104
105 //=======================================================================
106 //function : SetFace
107 //purpose  : 
108 //=======================================================================
109 void BRepMesh_FaceAttribute::SetFace (
110   const TopoDS_Face&     theFace, 
111   const Standard_Boolean theAdaptiveMin)
112 {
113   myFace        = theFace;
114   myAdaptiveMin = theAdaptiveMin;
115
116   init ();
117 }
118
119 //=======================================================================
120 //function : init
121 //purpose  : 
122 //=======================================================================
123 void BRepMesh_FaceAttribute::init()
124 {
125   myVertexEdgeMap = new BRepMesh::IMapOfInteger;
126   myInternalEdges = new BRepMesh::DMapOfShapePairOfPolygon;
127   myLocation2D    = new BRepMesh::DMapOfIntegerListOfXY;
128   myClassifier    = new BRepMesh_Classifier;
129
130   if (myFace.IsNull())
131     return;
132
133   BRepTools::Update(myFace);
134   myFace.Orientation(TopAbs_FORWARD);
135   BRepTools::UVBounds(myFace, myUMin, myUMax, myVMin, myVMax);
136
137   if (myAdaptiveMin) 
138   {
139     // compute minimal UV distance
140     // between vertices
141
142     myMinStep = RealLast();
143     for (TopoDS_Iterator aFaceIt(myFace); aFaceIt.More(); aFaceIt.Next()) 
144     {
145       for (TopoDS_Iterator aWireIt(aFaceIt.Value()); aWireIt.More(); aWireIt.Next()) 
146       {
147         const TopoDS_Edge& anEdge = TopoDS::Edge(aWireIt.Value());
148         if (anEdge.IsNull() || BRep_Tool::IsClosed(anEdge))
149           continue;
150
151         // Get end points on 2d curve
152         gp_Pnt2d aFirst2d, aLast2d;
153         BRep_Tool::UVPoints(anEdge, myFace, aFirst2d, aLast2d);
154         Standard_Real aDist =aFirst2d.Distance(aLast2d);
155         if (aDist < myMinStep) 
156           myMinStep = aDist;
157       }
158     }
159   }
160   
161   BRepAdaptor_Surface aSurfAdaptor(myFace, Standard_False);
162   mySurface = new BRepAdaptor_HSurface(aSurfAdaptor);
163 }
164
165 //=======================================================================
166 //function : Clear
167 //purpose  : 
168 //=======================================================================
169 void BRepMesh_FaceAttribute::Clear()
170 {
171   myStructure.Nullify();
172   myLocation2D->Clear();
173   myInternalEdges->Clear();
174   myVertexEdgeMap->Clear();
175 }
176
177 //=======================================================================
178 //function : computeParametricTolerance
179 //purpose  : 
180 //=======================================================================
181 Standard_Real BRepMesh_FaceAttribute::computeParametricTolerance(
182   const Standard_Real theFirstParam,
183   const Standard_Real theLastParam) const
184 {
185   const Standard_Real aDeflectionUV = 1.e-05;
186   Standard_Real aPreci = (theLastParam - theFirstParam) * aDeflectionUV;
187   if(myAdaptiveMin && myMinStep < aPreci)
188     aPreci = myMinStep;
189
190   return Max(Precision::PConfusion(), aPreci);
191 }
192
193 //=======================================================================
194 //function : getVertexIndex
195 //purpose  : 
196 //=======================================================================
197 Standard_Boolean BRepMesh_FaceAttribute::getVertexIndex(
198   const TopoDS_Vertex& theVertex,
199   Standard_Integer&    theVertexIndex) const
200 {
201   if (!myBoundaryVertices.IsNull() && myBoundaryVertices->IsBound(theVertex))
202     theVertexIndex = myBoundaryVertices->Find(theVertex);
203   else if (!mySurfaceVertices.IsNull() && mySurfaceVertices->IsBound(theVertex))
204     theVertexIndex = mySurfaceVertices->Find(theVertex);
205   else
206     return Standard_False;
207
208   return Standard_True;
209 }
210
211 //=======================================================================
212 //function : AddNode
213 //purpose  : 
214 //=======================================================================
215 void BRepMesh_FaceAttribute::AddNode(
216   const Standard_Integer         theIndex,
217   const gp_XY&                   theUV,
218   const BRepMesh_DegreeOfFreedom theMovability,
219   Standard_Integer&              theNodeIndex,
220   Standard_Integer&              theNodeOnEdgeIndex)
221 {
222   BRepMesh_Vertex aNode(theUV, theIndex, theMovability);
223   theNodeIndex = myStructure->AddNode(aNode);
224   theNodeOnEdgeIndex = myVertexEdgeMap->FindIndex(theNodeIndex);
225   if (theNodeOnEdgeIndex == 0)
226     theNodeOnEdgeIndex = myVertexEdgeMap->Add(theNodeIndex);
227 }
228
229 //=======================================================================
230 //function : Scale
231 //purpose  : 
232 //=======================================================================
233 gp_XY BRepMesh_FaceAttribute::Scale(const gp_XY&           thePoint2d,
234                                     const Standard_Boolean isToFaceBasis)
235 {
236   return isToFaceBasis ?
237     gp_XY((thePoint2d.X() - myUMin) / myDeltaX, (thePoint2d.Y() - myVMin) / myDeltaY) :
238     gp_XY(thePoint2d.X() * myDeltaX + myUMin, thePoint2d.Y() * myDeltaY + myVMin);
239 }
240
241 //=======================================================================
242 //function : ToleranceU
243 //purpose  : 
244 //=======================================================================
245 Standard_Real BRepMesh_FaceAttribute::ToleranceU() const
246 {
247   return computeParametricTolerance(myUMin, myUMax);
248 }
249
250 //=======================================================================
251 //function : ToleranceV
252 //purpose  : 
253 //=======================================================================
254 Standard_Real BRepMesh_FaceAttribute::ToleranceV() const
255 {
256   return computeParametricTolerance(myVMin, myVMax);
257 }