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

0032332: Modeling Algorithms - Incorrect result of ShapeUpgrade_UnifySameDomain

Method UnionPCurves of ShapeUpgrade_UnifySameDomain is modified: check of the range of new pcurves is added: if the range differs from the 3D-curve's one, the pcurves are being recomputed by projection.
This commit is contained in:
jgv 2021-04-28 22:54:03 +03:00 committed by jfa
parent 318ef16733
commit 7ba9b75f32
3 changed files with 101 additions and 32 deletions

View File

@ -53,8 +53,10 @@
#include <IntPatch_ImpImpIntersection.hxx> #include <IntPatch_ImpImpIntersection.hxx>
#include <ShapeAnalysis_Edge.hxx> #include <ShapeAnalysis_Edge.hxx>
#include <ShapeAnalysis_WireOrder.hxx> #include <ShapeAnalysis_WireOrder.hxx>
#include <ShapeAnalysis_Surface.hxx>
#include <ShapeBuild_Edge.hxx> #include <ShapeBuild_Edge.hxx>
#include <ShapeBuild_ReShape.hxx> #include <ShapeBuild_ReShape.hxx>
#include <ShapeConstruct_ProjectCurveOnSurface.hxx>
#include <ShapeFix_Edge.hxx> #include <ShapeFix_Edge.hxx>
#include <ShapeFix_Face.hxx> #include <ShapeFix_Face.hxx>
#include <ShapeFix_Shell.hxx> #include <ShapeFix_Shell.hxx>
@ -1489,6 +1491,11 @@ static TopoDS_Edge GlueEdgesWithPCurves(const TopTools_SequenceOfShape& aChain,
void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape& theChain, void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape& theChain,
TopoDS_Edge& theEdge) TopoDS_Edge& theEdge)
{ {
Standard_Real aFirst3d, aLast3d;
Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aFirst3d, aLast3d);
Standard_Real aTolEdge = BRep_Tool::Tolerance(theEdge);
Standard_Real aMaxTol = aTolEdge;
TopTools_SequenceOfShape aFaceSeq; TopTools_SequenceOfShape aFaceSeq;
const TopoDS_Edge& aFirstEdge = TopoDS::Edge(theChain.Value(1)); const TopoDS_Edge& aFirstEdge = TopoDS::Edge(theChain.Value(1));
@ -1686,7 +1693,6 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
} }
TColStd_Array1OfReal tabtolvertex(0, aTolVerSeq.Length() - 1); TColStd_Array1OfReal tabtolvertex(0, aTolVerSeq.Length() - 1);
Standard_Real aMaxTol = 0.0;
for (Standard_Integer i = 1; i <= aTolVerSeq.Length(); i++) for (Standard_Integer i = 1; i <= aTolVerSeq.Length(); i++)
{ {
Standard_Real aTol = aTolVerSeq(i); Standard_Real aTol = aTolVerSeq(i);
@ -1725,32 +1731,51 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
} }
BRep_Builder aBuilder; BRep_Builder aBuilder;
Standard_Real aTol = BRep_Tool::Tolerance(theEdge);
//Reparametrize pcurves if needed //Check the results for consistency
for (Standard_Integer ii = 2; ii <= ResPCurves.Length(); ii++) Standard_Boolean IsBadRange = Standard_False;
Standard_Real aRange3d = aLast3d - aFirst3d;
for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
{ {
if (Abs (ResFirsts(1) - ResFirsts(ii)) > Precision::Confusion() || Standard_Real aRange = ResLasts(ii) - ResFirsts(ii);
Abs (ResLasts(1) - ResLasts(ii)) > Precision::Confusion()) if (Abs (aRange3d - aRange) > aMaxTol)
IsBadRange = Standard_True;
}
if (IsBadRange)
{
for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
{ {
Handle(Geom2d_TrimmedCurve) aTrPCurve = const TopoDS_Face& aFace = TopoDS::Face (aFaceSeq(ii));
new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii), ResLasts(ii)); Handle(Geom_Surface) aSurf = BRep_Tool::Surface (aFace);
Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve); Handle(ShapeAnalysis_Surface) aSAS = new ShapeAnalysis_Surface (aSurf);
TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots()); ShapeConstruct_ProjectCurveOnSurface aToolProj;
aBSplinePCurve->Knots (aKnots); aToolProj.Init (aSAS, Precision::Confusion());
BSplCLib::Reparametrize (ResFirsts(1), ResLasts(1), aKnots); Handle(Geom2d_Curve) aNewPCurve;
aBSplinePCurve->SetKnots (aKnots); if (aToolProj.Perform(aCurve, aFirst3d, aLast3d, aNewPCurve))
ResPCurves(ii) = aBSplinePCurve; ResPCurves(ii) = aNewPCurve;
else
{
//Reparametrize pcurve
Handle(Geom2d_TrimmedCurve) aTrPCurve =
new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii), ResLasts(ii));
Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots());
aBSplinePCurve->Knots (aKnots);
BSplCLib::Reparametrize (aFirst3d, aLast3d, aKnots);
aBSplinePCurve->SetKnots (aKnots);
ResPCurves(ii) = aBSplinePCurve;
}
ResFirsts(ii) = aFirst3d;
ResLasts(ii) = aLast3d;
} }
} }
//Reparametrize 3d curve if needed //Reparametrize 3d curve if needed
if (!ResPCurves.IsEmpty()) if (!ResPCurves.IsEmpty())
{ {
Standard_Real aFirst, aLast; if (Abs (aFirst3d - ResFirsts(1)) > aMaxTol ||
Handle(Geom_Curve) aCurve = BRep_Tool::Curve (theEdge, aFirst, aLast); Abs (aLast3d - ResLasts(1)) > aMaxTol)
if (Abs (aFirst - ResFirsts(1)) > Precision::Confusion() ||
Abs (aLast - ResLasts(1)) > Precision::Confusion())
{ {
GeomAdaptor_Curve aGAcurve (aCurve); GeomAdaptor_Curve aGAcurve (aCurve);
GeomAbs_CurveType aType = aGAcurve.GetType(); GeomAbs_CurveType aType = aGAcurve.GetType();
@ -1758,12 +1783,13 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
{ {
gp_Lin aLin = aGAcurve.Line(); gp_Lin aLin = aGAcurve.Line();
gp_Dir aDir = aLin.Direction(); gp_Dir aDir = aLin.Direction();
gp_Pnt aPnt = aGAcurve.Value (aFirst); gp_Pnt aPnt = aGAcurve.Value (aFirst3d);
gp_Vec anOffset = -aDir; gp_Vec anOffset = -aDir;
anOffset *= ResFirsts(1); anOffset *= ResFirsts(1);
aPnt.Translate (anOffset); aPnt.Translate (anOffset);
Handle(Geom_Line) aLine = new Geom_Line (aPnt, aDir); Handle(Geom_Line) aLine = new Geom_Line (aPnt, aDir);
aBuilder.UpdateEdge (theEdge, aLine, aTol); aBuilder.UpdateEdge (theEdge, aLine, aTolEdge);
aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
} }
else if (aType == GeomAbs_Circle) else if (aType == GeomAbs_Circle)
{ {
@ -1771,29 +1797,36 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
Standard_Real aRadius = aCirc.Radius(); Standard_Real aRadius = aCirc.Radius();
gp_Ax2 aPosition = aCirc.Position(); gp_Ax2 aPosition = aCirc.Position();
gp_Ax1 anAxis = aPosition.Axis(); gp_Ax1 anAxis = aPosition.Axis();
Standard_Real anOffset = aFirst - ResFirsts(1); Standard_Real anOffset = aFirst3d - ResFirsts(1);
aPosition.Rotate (anAxis, anOffset); aPosition.Rotate (anAxis, anOffset);
Handle(Geom_Circle) aCircle = new Geom_Circle (aPosition, aRadius); Handle(Geom_Circle) aCircle = new Geom_Circle (aPosition, aRadius);
aBuilder.UpdateEdge (theEdge, aCircle, aTol); aBuilder.UpdateEdge (theEdge, aCircle, aTolEdge);
aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
} }
else //general case else //general case
{ {
Handle(Geom_TrimmedCurve) aTrCurve = for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
new Geom_TrimmedCurve (aCurve, aFirst, aLast); {
Handle(Geom_BSplineCurve) aBSplineCurve = GeomConvert::CurveToBSplineCurve(aTrCurve); if (Abs (aFirst3d - ResFirsts(ii)) > Precision::Confusion() ||
TColStd_Array1OfReal aKnots (1, aBSplineCurve->NbKnots()); Abs (aLast3d - ResLasts(ii)) > Precision::Confusion())
aBSplineCurve->Knots (aKnots); {
BSplCLib::Reparametrize (ResFirsts(1), ResLasts(1), aKnots); Handle(Geom2d_TrimmedCurve) aTrPCurve =
aBSplineCurve->SetKnots (aKnots); new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii), ResLasts(ii));
aBuilder.UpdateEdge (theEdge, aBSplineCurve, aTol); Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots());
aBSplinePCurve->Knots (aKnots);
BSplCLib::Reparametrize (aFirst3d, aLast3d, aKnots);
aBSplinePCurve->SetKnots (aKnots);
ResPCurves(ii) = aBSplinePCurve;
}
}
} }
} }
aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
} }
for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++) for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++)
{ {
aBuilder.UpdateEdge(theEdge, ResPCurves(j), TopoDS::Face(aFaceSeq(j)), aTol); aBuilder.UpdateEdge(theEdge, ResPCurves(j), TopoDS::Face(aFaceSeq(j)), aTolEdge);
} }
} }

View File

@ -0,0 +1,18 @@
puts "=========================================================="
puts "OCC32332: Incorrect result of ShapeUpgrade_UnifySameDomain"
puts "=========================================================="
puts ""
restore [locate_data_file bug32332_1.brep] a
unifysamedom result a
checkshape result
checknbshapes result -wire 4 -edge 9 -vertex 6
set tolres [checkmaxtol result]
if { ${tolres} > 2.e-7} {
puts "Error: bad tolerance of result"
}

View File

@ -0,0 +1,18 @@
puts "=========================================================="
puts "OCC32332: Incorrect result of ShapeUpgrade_UnifySameDomain"
puts "=========================================================="
puts ""
restore [locate_data_file bug32332_2.brep] a
unifysamedom result a
checkshape result
checknbshapes result -wire 4 -edge 12 -vertex 8
set tolres [checkmaxtol result]
if { ${tolres} > 2.e-7} {
puts "Error: bad tolerance of result"
}