1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0023650: Slow mesher: one bspline surface, 80 seconds for 132 triangles

Corrections in GeomLib::NormEstim, added norm computing using GeomLProp_SLProps.
Corrections in GeomLib::NormEstim, normal is computed with CSLib::Normal in case of a null normal.
Modified GeomLib::NormEstim Algo in case of null normal.
Added test case bugs/mesh/bug23650
This commit is contained in:
aml 2013-10-17 12:14:52 +04:00 committed by bugmaster
parent f933f9cf88
commit 2b21c64155
2 changed files with 81 additions and 116 deletions

View File

@ -137,6 +137,9 @@
#include <GeomConvert_CompCurveToBSplineCurve.hxx> #include <GeomConvert_CompCurveToBSplineCurve.hxx>
#include <GeomConvert_ApproxSurface.hxx> #include <GeomConvert_ApproxSurface.hxx>
#include <CSLib.hxx>
#include <CSLib_NormalStatus.hxx>
#include <Standard_ConstructionError.hxx> #include <Standard_ConstructionError.hxx>
@ -2341,12 +2344,6 @@ Standard_Integer GeomLib::NormEstim(const Handle(Geom_Surface)& S,
Standard_Real MDU = DU.SquareMagnitude(), MDV = DV.SquareMagnitude(); Standard_Real MDU = DU.SquareMagnitude(), MDV = DV.SquareMagnitude();
Standard_Real h, sign;
Standard_Boolean AlongV;
Handle(Geom_Curve) Iso;
Standard_Real t, first, last, bid1, bid2;
gp_Vec Tang;
if(MDU >= aTol2 && MDV >= aTol2) { if(MDU >= aTol2 && MDV >= aTol2) {
gp_Vec Norm = DU^DV; gp_Vec Norm = DU^DV;
Standard_Real Magn = Norm.SquareMagnitude(); Standard_Real Magn = Norm.SquareMagnitude();
@ -2357,125 +2354,62 @@ Standard_Integer GeomLib::NormEstim(const Handle(Geom_Surface)& S,
return 0; return 0;
} }
else if(MDU < aTol2 && MDV >= aTol2) {
AlongV = Standard_True;
Iso = S->UIso(UV.X());
t = UV.Y();
S->Bounds(bid1, bid2, first, last);
}
else if(MDU >= aTol2 && MDV < aTol2) {
AlongV = Standard_False;
Iso = S->VIso(UV.Y());
t = UV.X();
S->Bounds(first, last, bid1, bid2);
}
else { else {
return 3; gp_Vec D2U, D2V, D2UV;
} Standard_Boolean isDone;
CSLib_NormalStatus aStatus;
gp_Dir aNormal;
Standard_Real L = .001; S->D2(UV.X(), UV.Y(), DummyPnt, DU, DV, D2U, D2V, D2UV);
CSLib::Normal(DU, DV, D2U, D2V, D2UV, Tol, isDone, aStatus, aNormal);
if(Precision::IsInfinite(Abs(first))) first = t - 1.; if (isDone) {
if(Precision::IsInfinite(Abs(last))) last = t + 1.; Standard_Real Umin, Umax, Vmin, Vmax;
Standard_Real step = 1.0e-5;
if(last - t >= t - first) { Standard_Real eps = 1.0e-16;
sign = 1.; Standard_Real sign = 1;
}
else { S->Bounds(Umin, Umax, Vmin, Vmax);
sign = -1.; // Along V
} if(MDU < aTol2 && MDV >= aTol2) {
if (UV.Y() + step >= Vmax)
sign = -1.0;
S->D1(UV.X(), UV.Y() + sign * step, DummyPnt, DU, DV);
gp_Vec Norm = DU^DV;
if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0))
aNormal.Reverse();
Standard_Real hmax = .01*(last - first); }
if(AlongV) { // Along U
h = Min(L/sqrt(MDV), hmax); if(MDV < aTol2 && MDU >= aTol2) {
S->D1(UV.X(), UV.Y() + sign*h, DummyPnt, DU, DV); if (UV.X() + step >= Umax)
} sign = -1.0;
else { S->D1(UV.X() + sign * step, UV.Y(), DummyPnt, DU, DV);
h = Min(L/sqrt(MDU), hmax); gp_Vec Norm = DU^DV;
S->D1(UV.X() + sign*h, UV.Y(), DummyPnt, DU, DV); if ((Norm.SquareMagnitude() >= eps) && (Norm.Dot(aNormal) < 0.0))
} aNormal.Reverse();
}
gp_Vec DD; // quasysingular
if ((aStatus == CSLib_D1NuIsNull) || (aStatus == CSLib_D1NvIsNull) ||
gp_Vec NAux = DU^DV; (aStatus == CSLib_D1NuIsParallelD1Nv)) {
Standard_Real h1 = h; N.SetXYZ(aNormal.XYZ());
while(NAux.SquareMagnitude() < aTol2) { return 1;
h1 += h; }
if(AlongV) { // conical
Standard_Real v = UV.Y() + sign*h1; if (aStatus == CSLib_InfinityOfSolutions)
return 2;
if(v < first || v > last) return 3;
S->D1(UV.X(), v, DummyPnt, DU, DV);
} }
// computation is impossible
else { else {
Standard_Real v = UV.X() + sign*h1; // conical
if (aStatus == CSLib_D1NIsNull) {
if(v < first || v > last) return 3; return 2;
}
S->D1(v, UV.Y(), DummyPnt, DU, DV); return 3;
} }
NAux = DU^DV;
} }
return 3;
Iso->D2(t, DummyPnt, Tang, DD);
if(DD.SquareMagnitude() >= aTol2) {
gp_Vec NV = DD * (Tang * Tang) - Tang * (Tang * DD);
Standard_Real MagnNV = NV.SquareMagnitude();
if(MagnNV < aTol2) return 3;
MagnNV = sqrt(MagnNV);
N.SetXYZ(NV.XYZ()/MagnNV);
Standard_Real par = .5*(bid2+bid1);
if(AlongV) {
Iso = S->UIso(par);
}
else {
Iso = S->VIso(par);
}
Iso->D2(t, DummyPnt, Tang, DD);
gp_Vec N1V = DD * (Tang * Tang) - Tang * (Tang * DD);
Standard_Real MagnN1V = N1V.SquareMagnitude();
if(MagnN1V < aTol2) return 3;
MagnN1V = sqrt(MagnN1V);
gp_Dir N1(N1V.XYZ()/MagnN1V);
Standard_Integer res = 1;
if(N*N1 < 1. - Tol) res = 2;
if(N*NAux <= 0.) N.Reverse();
return res;
}
else {
//Seems to be conical singular point
if(AlongV) {
NAux = DU^Tang;
}
else {
NAux = Tang^DV;
}
sign = NAux.Magnitude();
if(sign < Tol) return 3;
N = NAux;
return 2;
}
} }

31
tests/bugs/mesh/bug23650 Normal file
View File

@ -0,0 +1,31 @@
puts "=========="
puts "OCC23650"
puts "=========="
puts ""
##################################################################
# Slow mesher: one bspline surface, 80 seconds for 132 triangles
##################################################################
restore [locate_data_file bug23650_slowmesh.brep] result
tclean result
dchrono h reset
dchrono h start
incmesh result 0.2
dchrono h stop
set info [dchrono h show]
regexp {CPU user time: ([-0-9.+eE]+) seconds} $info full cpu_time
if { $cpu_time > 5. } {
puts "Error : meshing is slow"
} else {
puts "OK: meshing is quite fast"
}
vinit
vdisplay result
vfit
vsetdispmode 1
set only_screen 1