0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / BRepMesh / BRepMesh_TorusRangeSplitter.cxx
CommitLineData
7bd071ed 1// Created on: 2016-07-07
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_TorusRangeSplitter.hxx>
17#include <GCPnts_TangentialDeflection.hxx>
18
19//=======================================================================
20// Function: GenerateSurfaceNodes
21// Purpose :
22//=======================================================================
23Handle(IMeshData::ListOfPnt2d) BRepMesh_TorusRangeSplitter::GenerateSurfaceNodes(
24 const IMeshTools_Parameters& theParameters) const
25{
26 const std::pair<Standard_Real, Standard_Real>& aRangeU = GetRangeU();
27 const std::pair<Standard_Real, Standard_Real>& aRangeV = GetRangeV();
28
29 const Standard_Real aDiffU = aRangeU.second - aRangeU.first;
30 const Standard_Real aDiffV = aRangeV.second - aRangeV.first;
31
32 const gp_Torus aTorus = GetDFace()->GetSurface()->Torus();
33 const Standard_Real r = aTorus.MinorRadius();
34 const Standard_Real R = aTorus.MajorRadius();
35
36 const Standard_Real oldDv = GCPnts_TangentialDeflection::ArcAngularStep(
37 r, GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
38
39 Standard_Real Dv = 0.9*oldDv; //TWOTHIRD * oldDv;
40 Dv = oldDv;
41
42 const Standard_Integer nbV = Max((Standard_Integer) (aDiffV / Dv), 2);
43 Dv = aDiffV / (nbV + 1);
44
45 Standard_Real Du;
46 const Standard_Real ru = R + r;
47 if (ru > 1.e-16)
48 {
49 Du = GCPnts_TangentialDeflection::ArcAngularStep(ru,
50 GetDFace()->GetDeflection(), theParameters.Angle, theParameters.MinSize);
51
52 const Standard_Real aa = sqrt(Du*Du + oldDv*oldDv);
53 if (aa < gp::Resolution())
54 {
55 return Handle(IMeshData::ListOfPnt2d)();
56 }
57
58 Du *= Min(oldDv, Du) / aa;
59 }
60 else
61 {
62 Du = Dv;
63 }
64
65 Standard_Integer nbU = Max((Standard_Integer) (aDiffU / Du), 2);
66 nbU = Max(nbU, (Standard_Integer) (nbV * aDiffU * R / (aDiffV * r) / 5.));
67 Du = aDiffU / (nbU + 1);
68
69 const Handle(NCollection_IncAllocator) aTmpAlloc =
70 new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
71
72 Handle(IMeshData::SequenceOfReal) aParamU, aParamV;
73 if (R < r)
74 {
75 // As the points of edges are returned.
76 // in this case, the points are not representative.
77
78 //-- Choose DeltaX and DeltaY so that to avoid skipping points on the grid
79 aParamU = new IMeshData::SequenceOfReal(aTmpAlloc);
80 for (Standard_Integer i = 0; i <= nbU; i++)
81 {
82 aParamU->Append(aRangeU.first + i * Du);
83 }
84 }//R<r
85 else //U if R > r
86 {
87 aParamU = fillParams(GetParametersU(), GetRangeU(), nbU, 0.5, aTmpAlloc);
88 }
89
90 aParamV = fillParams(GetParametersV(), GetRangeV(), nbV, 2. / 3., aTmpAlloc);
91
92 const std::pair<Standard_Real, Standard_Real> aNewRangeU(aRangeU.first + Du * 0.1,
93 aRangeU.second - Du * 0.1);
94
95 const std::pair<Standard_Real, Standard_Real> aNewRangeV(aRangeV.first + Dv * 0.1,
96 aRangeV.second - Dv * 0.1);
97
98 Handle(IMeshData::ListOfPnt2d) aNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
99 for (Standard_Integer i = 1; i <= aParamU->Length(); ++i)
100 {
101 const Standard_Real aPasU = aParamU->Value(i);
102 if (aPasU >= aNewRangeU.first && aPasU < aNewRangeU.second)
103 {
104 for (Standard_Integer j = 1; j <= aParamV->Length(); ++j)
105 {
106 const Standard_Real aPasV = aParamV->Value(j);
107 if (aPasV >= aNewRangeV.first && aPasV < aNewRangeV.second)
108 {
109 aNodes->Append(gp_Pnt2d(aPasU, aPasV));
110 }
111 }
112 }
113 }
114
115 return aNodes;
116}
117
118//=======================================================================
119// Function: AddPoint
120// Purpose :
121//=======================================================================
122void BRepMesh_TorusRangeSplitter::AddPoint(const gp_Pnt2d& thePoint)
123{
124 BRepMesh_DefaultRangeSplitter::AddPoint(thePoint);
125 GetParametersU().Add(thePoint.X());
126 GetParametersV().Add(thePoint.Y());
127}
128
129//=======================================================================
130// Function: fillParams
131// Purpose :
132//=======================================================================
133Handle(IMeshData::SequenceOfReal) BRepMesh_TorusRangeSplitter::fillParams(
134 const IMeshData::IMapOfReal& theParams,
135 const std::pair<Standard_Real, Standard_Real>& theRange,
136 const Standard_Integer theStepsNb,
137 const Standard_Real theScale,
138 const Handle(NCollection_IncAllocator)& theAllocator) const
139{
140 Handle(IMeshData::SequenceOfReal) aParams =
141 new IMeshData::SequenceOfReal(theAllocator);
142
143 const Standard_Integer aLength = theParams.Size();
144 TColStd_Array1OfReal aParamArray(1, aLength);
145
146 for (Standard_Integer j = 1; j <= aLength; ++j)
147 {
148 aParamArray(j) = theParams(j);
149 }
150
151 // Calculate DU, leave array of parameters
152 const Standard_Real aDiff = Abs(theRange.second - theRange.first);
153 Standard_Real aStep = FUN_CalcAverageDUV(aParamArray, aLength);
154 aStep = Max(aStep, aDiff / (Standard_Real) theStepsNb / 2.);
155
156 Standard_Real aStdStep = aDiff / (Standard_Real) aLength;
157 if (aStep > aStdStep)
158 {
159 aStdStep = aStep;
160 }
161 aStdStep *= theScale;
162
163 // Add parameters
164 for (Standard_Integer j = 1; j <= aLength; ++j)
165 {
166 const Standard_Real pp = aParamArray(j);
167
168 Standard_Boolean isToInsert = Standard_True;
169 const Standard_Integer aParamsLength = aParams->Length();
170 for (Standard_Integer i = 1; i <= aParamsLength && isToInsert; ++i)
171 {
172 isToInsert = (Abs(aParams->Value(i) - pp) > aStdStep);
173 }
174
175 if (isToInsert)
176 {
177 aParams->Append(pp);
178 }
179 }
180
181 return aParams;
182}
183
184//=======================================================================
185// Function: FUN_CalcAverageDUV
186// Purpose :
187//=======================================================================
188Standard_Real BRepMesh_TorusRangeSplitter::FUN_CalcAverageDUV(
189 TColStd_Array1OfReal& P, const Standard_Integer PLen) const
190{
191 Standard_Integer i, j, n = 0;
192 Standard_Real p, result = 0.;
193
194 for (i = 1; i <= PLen; i++)
195 {
196 // Sort
197 for (j = i + 1; j <= PLen; j++)
198 {
199 if (P(i) > P(j))
200 {
201 p = P(i);
202 P(i) = P(j);
203 P(j) = p;
204 }
205 }
206 // Accumulate
207 if (i != 1)
208 {
209 p = Abs(P(i) - P(i - 1));
210 if (p > 1.e-7)
211 {
212 result += p;
213 n++;
214 }
215 }
216 }
217 return (n ? (result / (Standard_Real) n) : -1.);
218}