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