diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index ad1471c3df..f1d9d50ce2 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -186,9 +186,10 @@ void BRepMesh_FastDiscretFace::initDataStructure() // Check the necessity to fill the map of parameters const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); GeomAbs_SurfaceType thetype = gFace->GetType(); - const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus || - thetype == GeomAbs_BezierSurface || - thetype == GeomAbs_BSplineSurface); + const Standard_Boolean isBSpline = (thetype == GeomAbs_BezierSurface || + thetype == GeomAbs_BSplineSurface); + const Standard_Boolean useUVParam = (thetype == GeomAbs_Torus ||isBSpline); + myUParam.Clear(); myVParam.Clear(); @@ -217,6 +218,40 @@ void BRepMesh_FastDiscretFace::initDataStructure() } aBoundaryNodes.Nullify(); + if (isBSpline) + { + const Standard_Real aRange[2][2] = { + {myAttribute->GetUMin(), myAttribute->GetUMax()}, + {myAttribute->GetVMin(), myAttribute->GetVMax()} + }; + + const GeomAbs_Shape aContinuity = GeomAbs_CN; + for (Standard_Integer i = 0; i < 2; ++i) + { + const Standard_Boolean isU = (i == 0); + const Standard_Integer aIntervalsNb = isU ? + gFace->NbUIntervals(aContinuity) : + gFace->NbVIntervals(aContinuity); + + BRepMesh::IMapOfReal& aParams = isU ? myUParam : myVParam; + if (aIntervalsNb < aParams.Size()) + continue; + + TColStd_Array1OfReal aIntervals(1, aIntervalsNb + 1); + if (isU) + gFace->UIntervals(aIntervals, aContinuity); + else + gFace->VIntervals(aIntervals, aContinuity); + + for (Standard_Integer j = 1; j <= aIntervals.Upper(); ++j) + { + const Standard_Real aParam = aIntervals(j); + if (aParam > aRange[i][0] && aParam < aRange[i][1]) + aParams.Add(aParam); + } + } + } + //////////////////////////////////////////////////////////// //add internal vertices after self-intersection check if ( myInternalVerticesMode ) @@ -914,25 +949,30 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesBSpline( { aPrevParam2 = aParam2; aPrevPnt2 = aPnt2; - - if (!isU && j < aParams2.Length()) - { - // Update point parameter. - aStPnt1.SetX(aPrevParam2); - - // Classify intersection point - if (aClassifier->Perform(aStPnt1) == TopAbs_IN) - { - insertVertex(aPrevPnt2, aStPnt1.Coord(), theNewVertices); - } - } - ++j; } } } } } + + // insert nodes of the regular grid + for (Standard_Integer i = 1; i <= aParams[0].Length(); ++i) + { + const Standard_Real aParam1 = aParams[0].Value(i); + for (Standard_Integer j = 1; j <= aParams[1].Length(); ++j) + { + gp_Pnt2d aPnt2d(aParam1, aParams[1].Value(j)); + + // Classify intersection point + if (aClassifier->Perform(aPnt2d) == TopAbs_IN) + { + gp_Pnt aPnt; + gFace->D0(aPnt2d.X(), aPnt2d.Y(), aPnt); + insertVertex(aPnt, aPnt2d.Coord(), theNewVertices); + } + } + } } //======================================================================= diff --git a/tests/bugs/mesh/bug25519 b/tests/bugs/mesh/bug25519 new file mode 100755 index 0000000000..02c79e9cc7 --- /dev/null +++ b/tests/bugs/mesh/bug25519 @@ -0,0 +1,45 @@ +puts "================" +puts "CR25519" +puts "================" +puts "" +############################################### +## BRepMesh can break mesh regularity for BSpline surfaces +############################################### + +restore [locate_data_file bug25519_testtriangulation.brep] a + +tclean a +incmesh a 0.01 +front +fit +isos a 0 +triangles a + +set trinfo_s [trinfo a] +regexp {([0-9]+) triangles} ${trinfo_s} str nbtri_s +regexp {([0-9]+) nodes} ${trinfo_s} str nbnod_s +regexp {deflection ([0-9.+e-]+)} ${trinfo_s} str defl_s + +set good_nbtri 2721 +set good_nbnod 1405 +set good_defl 0.082010129769776202 + +set good_percent 5 + +set nbtri_percent [expr abs (${good_nbtri} - ${nbtri_s}) / double (${nbtri_s}) * 100 ] +set nbnod_percent [expr abs (${good_nbnod} - ${nbnod_s}) / double (${nbnod_s}) * 100 ] +set defl_percent [expr abs (${good_defl} - ${defl_s}) / ${defl_s} * 100 ] + +if { ${nbtri_percent} > ${good_percent} } { + puts "Error: triangle number is bad, it has changed to ${nbtri_percent} %" +} + +if { ${nbnod_percent} > ${good_percent} } { + puts "Error: node number is bad, it has changed to ${nbnod_percent} %" +} + +if { ${defl_percent} > ${good_percent} } { + puts "Error: deflection is bad, it has changed to ${defl_percent} %" +} + +set only_screen_axo 1 diff --git a/tests/mesh/data/advanced/B6 b/tests/mesh/data/advanced/B6 index 9da4deb93d..fec0a49b85 100755 --- a/tests/mesh/data/advanced/B6 +++ b/tests/mesh/data/advanced/B6 @@ -1 +1,7 @@ set TheFileName OCC22247.brep +if { [string compare $command "incmesh"] == 0 || + [string compare $command "mesh"] == 0 || + [string compare $command "incmesh_parallel"] == 0 } { + set bug_area "OCC25519" + set rel_tol 1.3654 +}