0026106: BRepMesh - revision of data model
[occt.git] / src / BRepMesh / BRepMesh_Deflection.cxx
1 // Created on: 2016-04-19
2 // Copyright (c) 2016 OPEN CASCADE SAS
3 // Created by: Oleg AGASHIN
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <BRepMesh_Deflection.hxx>
17 #include <BRepMesh_ShapeTool.hxx>
18 #include <IMeshTools_Parameters.hxx>
19 #include <IMeshData_Edge.hxx>
20 #include <IMeshData_Wire.hxx>
21 #include <IMeshData_Face.hxx>
22 #include <BRep_Tool.hxx>
23 #include <Bnd_Box.hxx>
24 #include <BRepBndLib.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopExp.hxx>
28
29 //=======================================================================
30 //function : RelativeEdgeDeflection
31 //purpose  : 
32 //=======================================================================
33 Standard_Real BRepMesh_Deflection::RelativeEdgeDeflection(
34   const TopoDS_Edge&  theEdge,
35   const Standard_Real theDeflection,
36   const Standard_Real theMaxShapeSize,
37   Standard_Real&      theAdjustmentCoefficient)
38 {
39   theAdjustmentCoefficient = 1.;
40   Standard_Real aEdgeDeflection = theDeflection;
41   if (theEdge.IsNull())
42   {
43     return aEdgeDeflection;
44   }
45
46   Bnd_Box aBox;
47   BRepBndLib::Add (theEdge, aBox, Standard_False);
48   BRepMesh_ShapeTool::BoxMaxDimension (aBox, aEdgeDeflection);
49
50   // Adjust resulting value in relation to the total size
51   theAdjustmentCoefficient = theMaxShapeSize / (2 * aEdgeDeflection);
52   if (theAdjustmentCoefficient < 0.5)
53   {
54     theAdjustmentCoefficient = 0.5;
55   }
56   else if (theAdjustmentCoefficient > 2.)
57   {
58     theAdjustmentCoefficient = 2.;
59   }
60
61   return (theAdjustmentCoefficient * aEdgeDeflection * theDeflection);
62 }
63
64 //=======================================================================
65 // Function: ComputeDeflection (edge)
66 // Purpose : 
67 //=======================================================================
68 void BRepMesh_Deflection::ComputeDeflection (
69   const IMeshData::IEdgeHandle& theDEdge,
70   const Standard_Real           theMaxShapeSize,
71   const IMeshTools_Parameters&  theParameters)
72 {
73   Standard_Real aLinDeflection;
74   Standard_Real aAngDeflection;
75   if (theParameters.Relative)
76   {
77     Standard_Real aScale;
78     aLinDeflection = RelativeEdgeDeflection (theDEdge->GetEdge (),
79       theParameters.Deflection, theMaxShapeSize, aScale);
80
81     // Is it OK?
82     aAngDeflection = theParameters.Angle * aScale;
83   }
84   else
85   {
86     aLinDeflection = theParameters.Deflection;
87     aAngDeflection = theParameters.Angle;
88   }
89
90   const TopoDS_Edge& anEdge = theDEdge->GetEdge();
91
92   TopoDS_Vertex aFirstVertex, aLastVertex;
93   TopExp::Vertices(anEdge, aFirstVertex, aLastVertex);
94
95   Handle(Geom_Curve) aCurve;
96   Standard_Real aFirstParam, aLastParam;
97   if (BRepMesh_ShapeTool::Range(anEdge, aCurve, aFirstParam, aLastParam))
98   {
99     const Standard_Real aDistF = aFirstVertex.IsNull() ? -1.0 : 
100                         BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam));
101     const Standard_Real aDistL = aLastVertex.IsNull()  ? -1.0 :
102                         BRep_Tool::Pnt(aLastVertex).Distance(aCurve->Value(aLastParam));
103
104     const Standard_Real aVertexAdjustDistance = Max(aDistF, aDistL);
105
106     aLinDeflection = Max(aVertexAdjustDistance, aLinDeflection);
107   }
108
109   theDEdge->SetDeflection        (aLinDeflection);
110   theDEdge->SetAngularDeflection (aAngDeflection);
111 }
112
113 //=======================================================================
114 // Function: ComputeDeflection (wire)
115 // Purpose : 
116 //=======================================================================
117 void BRepMesh_Deflection::ComputeDeflection (
118   const IMeshData::IWireHandle& theDWire,
119   const IMeshTools_Parameters&  theParameters)
120 {
121   Standard_Real aWireDeflection = 0.;
122   if (theDWire->EdgesNb () > 0)
123   {
124     for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
125     {
126       aWireDeflection += theDWire->GetEdge(aEdgeIt)->GetDeflection();
127     }
128
129     aWireDeflection /= theDWire->EdgesNb ();
130   }
131   else
132   {
133     aWireDeflection = theParameters.Deflection;
134   }
135
136   theDWire->SetDeflection (aWireDeflection);
137 }
138
139 //=======================================================================
140 // Function: ComputeDeflection (face)
141 // Purpose : 
142 //=======================================================================
143 void BRepMesh_Deflection::ComputeDeflection (
144   const IMeshData::IFaceHandle& theDFace,
145   const IMeshTools_Parameters&  theParameters)
146 {
147   Standard_Real aFaceDeflection = 0.;
148   if (theDFace->WiresNb () > 0)
149   {
150     for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb(); ++aWireIt)
151     {
152       aFaceDeflection += theDFace->GetWire(aWireIt)->GetDeflection();
153     }
154
155     aFaceDeflection /= theDFace->WiresNb ();
156   }
157   else
158   {
159     aFaceDeflection = theParameters.Deflection;
160   }
161
162   theDFace->SetDeflection (Max(2.* BRepMesh_ShapeTool::MaxFaceTolerance(
163     theDFace->GetFace()), aFaceDeflection));
164 }