mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0032719: Modelling Algorithms - UnifySameDomain result has incorrect triangulation
Correct method ShapeUpgrade_UnifySameDomain::UnionPCurves: reparametrize unified pcurves to fit the new range of 3D-curve.
This commit is contained in:
parent
cdb006be8e
commit
70af2be481
@ -22,6 +22,7 @@
|
|||||||
#include <BRepTopAdaptor_TopolTool.hxx>
|
#include <BRepTopAdaptor_TopolTool.hxx>
|
||||||
#include <GC_MakeCircle.hxx>
|
#include <GC_MakeCircle.hxx>
|
||||||
#include <Geom2d_Line.hxx>
|
#include <Geom2d_Line.hxx>
|
||||||
|
#include <Geom2d_Circle.hxx>
|
||||||
#include <GCE2d_MakeLine.hxx>
|
#include <GCE2d_MakeLine.hxx>
|
||||||
#include <Geom2d_TrimmedCurve.hxx>
|
#include <Geom2d_TrimmedCurve.hxx>
|
||||||
#include <Geom2dConvert.hxx>
|
#include <Geom2dConvert.hxx>
|
||||||
@ -1601,9 +1602,6 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
|
|||||||
if (isFound)
|
if (isFound)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Standard_Real aFirst, aLast;
|
|
||||||
Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, aFirst, aLast);
|
|
||||||
|
|
||||||
aFaceSeq.Append (aFace);
|
aFaceSeq.Append (aFace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1648,6 +1646,9 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
|
|||||||
|
|
||||||
if (aPCurveSeq.IsEmpty()) {
|
if (aPCurveSeq.IsEmpty()) {
|
||||||
Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
|
Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
|
||||||
|
if (aCopyPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
||||||
|
aCopyPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aCopyPCurve))->BasisCurve();
|
||||||
|
|
||||||
aPCurveSeq.Append(aCopyPCurve);
|
aPCurveSeq.Append(aCopyPCurve);
|
||||||
aFirstsSeq.Append(aFirst);
|
aFirstsSeq.Append(aFirst);
|
||||||
aLastsSeq.Append(aLast);
|
aLastsSeq.Append(aLast);
|
||||||
@ -1722,6 +1723,9 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
|
Handle(Geom2d_Curve) aCopyPCurve = Handle(Geom2d_Curve)::DownCast(aPCurve->Copy());
|
||||||
|
if (aCopyPCurve->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve)))
|
||||||
|
aCopyPCurve = (Handle(Geom2d_TrimmedCurve)::DownCast(aCopyPCurve))->BasisCurve();
|
||||||
|
|
||||||
aPCurveSeq.Append(aCopyPCurve);
|
aPCurveSeq.Append(aCopyPCurve);
|
||||||
aFirstsSeq.Append(aFirst);
|
aFirstsSeq.Append(aFirst);
|
||||||
aLastsSeq.Append(aLast);
|
aLastsSeq.Append(aLast);
|
||||||
@ -1842,57 +1846,53 @@ void ShapeUpgrade_UnifySameDomain::UnionPCurves(const TopTools_SequenceOfShape&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Reparametrize 3d curve if needed
|
//Reparametrize pcurves if needed
|
||||||
if (!ResPCurves.IsEmpty())
|
if (!ResPCurves.IsEmpty())
|
||||||
{
|
{
|
||||||
if (Abs (aFirst3d - ResFirsts(1)) > aMaxTol ||
|
for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
|
||||||
Abs (aLast3d - ResLasts(1)) > aMaxTol)
|
|
||||||
{
|
{
|
||||||
GeomAdaptor_Curve aGAcurve (aCurve);
|
if (Abs (aFirst3d - ResFirsts(ii)) > aMaxTol ||
|
||||||
GeomAbs_CurveType aType = aGAcurve.GetType();
|
Abs (aLast3d - ResLasts(ii)) > aMaxTol)
|
||||||
if (aType == GeomAbs_Line)
|
|
||||||
{
|
{
|
||||||
gp_Lin aLin = aGAcurve.Line();
|
Geom2dAdaptor_Curve aGAcurve (ResPCurves(ii));
|
||||||
gp_Dir aDir = aLin.Direction();
|
GeomAbs_CurveType aType = aGAcurve.GetType();
|
||||||
gp_Pnt aPnt = aGAcurve.Value (aFirst3d);
|
if (aType == GeomAbs_Line)
|
||||||
gp_Vec anOffset = -aDir;
|
|
||||||
anOffset *= ResFirsts(1);
|
|
||||||
aPnt.Translate (anOffset);
|
|
||||||
Handle(Geom_Line) aLine = new Geom_Line (aPnt, aDir);
|
|
||||||
aBuilder.UpdateEdge (theEdge, aLine, aTolEdge);
|
|
||||||
aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
|
|
||||||
}
|
|
||||||
else if (aType == GeomAbs_Circle)
|
|
||||||
{
|
|
||||||
gp_Circ aCirc = aGAcurve.Circle();
|
|
||||||
Standard_Real aRadius = aCirc.Radius();
|
|
||||||
gp_Ax2 aPosition = aCirc.Position();
|
|
||||||
gp_Ax1 anAxis = aPosition.Axis();
|
|
||||||
Standard_Real anOffset = aFirst3d - ResFirsts(1);
|
|
||||||
aPosition.Rotate (anAxis, anOffset);
|
|
||||||
Handle(Geom_Circle) aCircle = new Geom_Circle (aPosition, aRadius);
|
|
||||||
aBuilder.UpdateEdge (theEdge, aCircle, aTolEdge);
|
|
||||||
aBuilder.Range(theEdge, ResFirsts(1), ResLasts(1));
|
|
||||||
}
|
|
||||||
else //general case
|
|
||||||
{
|
|
||||||
for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
|
|
||||||
{
|
{
|
||||||
if (Abs (aFirst3d - ResFirsts(ii)) > Precision::Confusion() ||
|
gp_Lin2d aLin2d = aGAcurve.Line();
|
||||||
Abs (aLast3d - ResLasts(ii)) > Precision::Confusion())
|
gp_Dir2d aDir2d = aLin2d.Direction();
|
||||||
{
|
gp_Pnt2d aPnt2d = aGAcurve.Value(ResFirsts(ii));
|
||||||
Handle(Geom2d_TrimmedCurve) aTrPCurve =
|
gp_Vec2d anOffset = -aDir2d;
|
||||||
new Geom2d_TrimmedCurve (ResPCurves(ii), ResFirsts(ii), ResLasts(ii));
|
anOffset *= aFirst3d;
|
||||||
Handle(Geom2d_BSplineCurve) aBSplinePCurve = Geom2dConvert::CurveToBSplineCurve(aTrPCurve);
|
aPnt2d.Translate (anOffset);
|
||||||
TColStd_Array1OfReal aKnots (1, aBSplinePCurve->NbKnots());
|
Handle(Geom2d_Line) aNewLine2d = new Geom2d_Line (aPnt2d, aDir2d);
|
||||||
aBSplinePCurve->Knots (aKnots);
|
ResPCurves(ii) = aNewLine2d;
|
||||||
BSplCLib::Reparametrize (aFirst3d, aLast3d, aKnots);
|
|
||||||
aBSplinePCurve->SetKnots (aKnots);
|
|
||||||
ResPCurves(ii) = aBSplinePCurve;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
else if (aType == GeomAbs_Circle)
|
||||||
}
|
{
|
||||||
|
gp_Circ2d aCirc2d = aGAcurve.Circle();
|
||||||
|
Standard_Real aRadius = aCirc2d.Radius();
|
||||||
|
gp_Ax22d aPosition = aCirc2d.Position();
|
||||||
|
gp_Pnt2d aLocation = aCirc2d.Location();
|
||||||
|
Standard_Real anOffset = ResFirsts(ii) - aFirst3d;
|
||||||
|
aPosition.Rotate (aLocation, anOffset);
|
||||||
|
Handle(Geom2d_Circle) aNewCircle2d = new Geom2d_Circle (aPosition, aRadius);
|
||||||
|
ResPCurves(ii) = aNewCircle2d;
|
||||||
|
}
|
||||||
|
else //general case
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
} //if ranges > aMaxTol
|
||||||
|
} //for (Standard_Integer ii = 1; ii <= ResPCurves.Length(); ii++)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++)
|
for (Standard_Integer j = 1; j <= ResPCurves.Length(); j++)
|
||||||
|
20
tests/bugs/heal/bug32719
Normal file
20
tests/bugs/heal/bug32719
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
puts "============================================================"
|
||||||
|
puts "OCC32719: UnifySameDomain result has incorrect triangulation"
|
||||||
|
puts "============================================================"
|
||||||
|
puts ""
|
||||||
|
|
||||||
|
restore [locate_data_file bug32719.brep] a
|
||||||
|
|
||||||
|
unifysamedom result a
|
||||||
|
|
||||||
|
checkshape result
|
||||||
|
|
||||||
|
checknbshapes result -t -solid 4 -shell 4 -face 20 -wire 20 -edge 32 -vertex 16
|
||||||
|
|
||||||
|
set tolres [checkmaxtol result]
|
||||||
|
|
||||||
|
if { ${tolres} > 6.e-6} {
|
||||||
|
puts "Error: bad tolerance of result"
|
||||||
|
}
|
||||||
|
|
||||||
|
checkprops result -s 0.0222593 -v 5.17261e-05
|
Loading…
x
Reference in New Issue
Block a user