0031251: Add a new meshing parameter to enforce face linear deflection
[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
18 #include <Bnd_Box.hxx>
19 #include <BRepBndLib.hxx>
20 #include <BRepMesh_ShapeTool.hxx>
21 #include <IMeshData_Edge.hxx>
22 #include <IMeshData_Wire.hxx>
23 #include <IMeshTools_Parameters.hxx>
24 #include <TopExp.hxx>
25 #include <TopoDS_Vertex.hxx>
26
27 //=======================================================================
28 //function : RelativeEdgeDeflection
29 //purpose  : 
30 //=======================================================================
31 Standard_Real BRepMesh_Deflection::ComputeAbsoluteDeflection(
32   const TopoDS_Shape& theShape,
33   const Standard_Real theRelativeDeflection,
34   const Standard_Real theMaxShapeSize)
35 {
36   if (theShape.IsNull())
37   {
38     return theRelativeDeflection;
39   }
40
41   Bnd_Box aBox;
42   BRepBndLib::Add (theShape, aBox, Standard_False);
43
44   Standard_Real aShapeSize = theRelativeDeflection;
45   BRepMesh_ShapeTool::BoxMaxDimension (aBox, aShapeSize);
46
47   // Adjust resulting value in relation to the total size
48
49   Standard_Real aX1, aY1, aZ1, aX2, aY2, aZ2;
50   aBox.Get(aX1, aY1, aZ1, aX2, aY2, aZ2);
51   const Standard_Real aMaxShapeSize = (theMaxShapeSize > 0.0) ? theMaxShapeSize :
52                                        Max(aX2 - aX1, Max(aY2 - aY1, aZ2 - aZ1));
53
54   Standard_Real anAdjustmentCoefficient = aMaxShapeSize / (2 * aShapeSize);
55   if (anAdjustmentCoefficient < 0.5)
56   {
57     anAdjustmentCoefficient = 0.5;
58   }
59   else if (anAdjustmentCoefficient > 2.)
60   {
61     anAdjustmentCoefficient = 2.;
62   }
63
64   return (anAdjustmentCoefficient * aShapeSize * theRelativeDeflection);
65 }
66
67 //=======================================================================
68 // Function: ComputeDeflection (edge)
69 // Purpose : 
70 //=======================================================================
71 void BRepMesh_Deflection::ComputeDeflection (
72   const IMeshData::IEdgeHandle& theDEdge,
73   const Standard_Real           theMaxShapeSize,
74   const IMeshTools_Parameters&  theParameters)
75 {
76   const Standard_Real aAngDeflection = theParameters.Angle;
77   Standard_Real aLinDeflection =
78     !theParameters.Relative ? theParameters.Deflection :
79     ComputeAbsoluteDeflection(theDEdge->GetEdge(),
80                               theParameters.Deflection,
81                               theMaxShapeSize);
82
83   const TopoDS_Edge& anEdge = theDEdge->GetEdge();
84
85   TopoDS_Vertex aFirstVertex, aLastVertex;
86   TopExp::Vertices(anEdge, aFirstVertex, aLastVertex);
87
88   Handle(Geom_Curve) aCurve;
89   Standard_Real aFirstParam, aLastParam;
90   if (BRepMesh_ShapeTool::Range(anEdge, aCurve, aFirstParam, aLastParam))
91   {
92     const Standard_Real aDistF = aFirstVertex.IsNull() ? -1.0 : 
93                         BRep_Tool::Pnt(aFirstVertex).Distance(aCurve->Value(aFirstParam));
94     const Standard_Real aDistL = aLastVertex.IsNull()  ? -1.0 :
95                         BRep_Tool::Pnt(aLastVertex).Distance(aCurve->Value(aLastParam));
96
97     const Standard_Real aVertexAdjustDistance = Max(aDistF, aDistL);
98
99     aLinDeflection = Max(aVertexAdjustDistance, aLinDeflection);
100   }
101
102   theDEdge->SetDeflection        (aLinDeflection);
103   theDEdge->SetAngularDeflection (aAngDeflection);
104 }
105
106 //=======================================================================
107 // Function: ComputeDeflection (wire)
108 // Purpose : 
109 //=======================================================================
110 void BRepMesh_Deflection::ComputeDeflection (
111   const IMeshData::IWireHandle& theDWire,
112   const IMeshTools_Parameters&  theParameters)
113 {
114   Standard_Real aWireDeflection = 0.;
115   if (theDWire->EdgesNb () > 0)
116   {
117     for (Standard_Integer aEdgeIt = 0; aEdgeIt < theDWire->EdgesNb(); ++aEdgeIt)
118     {
119       aWireDeflection += theDWire->GetEdge(aEdgeIt)->GetDeflection();
120     }
121
122     aWireDeflection /= theDWire->EdgesNb ();
123   }
124   else
125   {
126     aWireDeflection = theParameters.Deflection;
127   }
128
129   theDWire->SetDeflection (aWireDeflection);
130 }
131
132 //=======================================================================
133 // Function: ComputeDeflection (face)
134 // Purpose : 
135 //=======================================================================
136 void BRepMesh_Deflection::ComputeDeflection (
137   const IMeshData::IFaceHandle& theDFace,
138   const IMeshTools_Parameters&  theParameters)
139 {
140   Standard_Real aDeflection = theParameters.DeflectionInterior;
141   if (theParameters.Relative)
142   {
143     aDeflection = ComputeAbsoluteDeflection(theDFace->GetFace(),
144                                             aDeflection, -1.0);
145   }
146
147   Standard_Real aFaceDeflection = 0.0;
148   if (!theParameters.ForceFaceDeflection)
149   {
150     if (theDFace->WiresNb () > 0)
151     {
152       for (Standard_Integer aWireIt = 0; aWireIt < theDFace->WiresNb (); ++aWireIt)
153       {
154         aFaceDeflection += theDFace->GetWire (aWireIt)->GetDeflection ();
155       }
156
157       aFaceDeflection /= theDFace->WiresNb ();
158     }
159
160     aFaceDeflection = Max (2. * BRepMesh_ShapeTool::MaxFaceTolerance (
161       theDFace->GetFace ()), aFaceDeflection);
162   }
163   aFaceDeflection = Max (aDeflection, aFaceDeflection);
164
165   theDFace->SetDeflection (aFaceDeflection);
166 }