1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0024470: Wrong result done by General Fuse algorithm.

Modifications:
1. The validity of the intersection point between edge and face is checked with sum of the tolerance values of the edge and face.
2. The intersection between toroidal surface and one of the following surfaces: Plane, Cylinder, Sphere, Cone or Torus
   is treated as analytical in the following cases:
   1) Torus and Plane: a. Axes of the surfaces are parallel;
                       b. Axes of the surfaces are perpendicular and location of the torus is lying on the plane;
   2) Torus and Sphere: The location of the sphere is lying on the line made from toruses axis;
   3) Torus and Cone, Cylinder or Torus: The axis of the surfaces are collinear.
   In all cases the intersection line(s) is(are) circle(s).

Added test cases bugs/modalg_5/bug24470

The intersection between torus with minor radius more than (or equal to) the major radius and any other surface is considered as parametric.
This commit is contained in:
emv
2014-01-09 12:01:01 +04:00
committed by bugmaster
parent 547702a15d
commit 7eed5d29a9
21 changed files with 2489 additions and 1360 deletions

View File

@@ -27,7 +27,8 @@ uses Ax3 from gp,
Pln from gp,
Cylinder from gp,
Sphere from gp,
Cone from gp,
Cone from gp,
Torus from gp,
SurfaceType from GeomAbs
is
@@ -55,6 +56,11 @@ is
Create(C: Cone from gp)
returns Quadric from IntSurf;
Create(T: Torus from gp)
returns Quadric from IntSurf;
SetValue(me: in out; P: Pln from gp)
@@ -75,6 +81,10 @@ is
SetValue(me: in out; C: Cone from gp)
is static;
SetValue(me: in out; T: Torus from gp)
is static;
Distance(me; P: Pnt from gp)
@@ -135,6 +145,14 @@ is
---C++: inline
is static;
Torus(me)
returns Torus from gp
---C++: inline
is static;

View File

@@ -20,7 +20,6 @@
#include <gp.hxx>
// ============================================================
IntSurf_Quadric::IntSurf_Quadric ():typ(GeomAbs_OtherSurface),
prm1(0.), prm2(0.), prm3(0.), prm4(0.)
@@ -63,6 +62,18 @@ IntSurf_Quadric::IntSurf_Quadric (const gp_Cone& C):
prm4 = 0.0;
}
// ============================================================
IntSurf_Quadric::IntSurf_Quadric (const gp_Torus& T):
ax3(T.Position()),typ(GeomAbs_Torus)
{
ax3direc = ax3.Direct();
lin.SetPosition(ax3.Axis());
prm1 = T.MajorRadius();
prm2 = T.MinorRadius();
prm3 = 0.0;
prm4 = 0.0;
}
// ============================================================
void IntSurf_Quadric::SetValue (const gp_Pln& P)
{
typ = GeomAbs_Plane;
@@ -103,6 +114,18 @@ void IntSurf_Quadric::SetValue (const gp_Cone& C)
prm4 = 0.0;
}
// ============================================================
void IntSurf_Quadric::SetValue (const gp_Torus& T)
{
typ = GeomAbs_Torus;
ax3 = T.Position();
ax3direc = ax3.Direct();
lin.SetPosition(ax3.Axis());
prm1 = T.MajorRadius();
prm2 = T.MinorRadius();
prm3 = 0.0;
prm4 = 0.0;
}
// ============================================================
Standard_Real IntSurf_Quadric::Distance (const gp_Pnt& P) const {
switch (typ) {
case GeomAbs_Plane: // plan
@@ -121,6 +144,21 @@ Standard_Real IntSurf_Quadric::Distance (const gp_Pnt& P) const {
dist = (dist-distp)/prm3;
return(dist);
}
case GeomAbs_Torus: // torus
{
gp_Pnt O, Pp, PT;
//
O = ax3.Location();
gp_Vec OZ (ax3.Direction());
Pp = P.Translated(OZ.Multiplied(-(gp_Vec(O,P).Dot(ax3.Direction()))));
//
gp_Dir DOPp = (O.SquareDistance(Pp) < 1e-14) ?
ax3.XDirection() : gp_Dir(gp_Vec(O, Pp));
PT.SetXYZ(O.XYZ() + DOPp.XYZ()*prm1);
//
Standard_Real dist = P.Distance(PT) - prm2;
return dist;
}
default:
{
}
@@ -163,11 +201,29 @@ gp_Vec IntSurf_Quadric::Gradient (const gp_Pnt& P) const {
ElSLib::ConeD1(U,V,ax3,prm1,prm2,Pp,D1u,D1v);
grad=D1u.Crossed(D1v);
if(ax3direc==Standard_False) {
grad.Reverse();
grad.Reverse();
}
grad.Normalize();
}
break;
case GeomAbs_Torus: // torus
{
gp_Pnt O, Pp, PT;
//
O = ax3.Location();
gp_Vec OZ (ax3.Direction());
Pp = P.Translated(OZ.Multiplied(-(gp_Vec(O,P).Dot(ax3.Direction()))));
//
gp_Dir DOPp = (O.SquareDistance(Pp) < 1e-14) ?
ax3.XDirection() : gp_Dir(gp_Vec(O, Pp));
PT.SetXYZ(O.XYZ() + DOPp.XYZ()*prm1);
//
grad.SetXYZ(P.XYZ() - PT.XYZ());
Standard_Real N = grad.Magnitude();
if(N>1e-14) { grad.Divide(N); }
else { grad.SetCoord(0., 0., 0.); }
}
break;
default:
{}
break;
@@ -176,8 +232,8 @@ gp_Vec IntSurf_Quadric::Gradient (const gp_Pnt& P) const {
}
// ============================================================
void IntSurf_Quadric::ValAndGrad (const gp_Pnt& P,
Standard_Real& Dist,
gp_Vec& Grad) const
Standard_Real& Dist,
gp_Vec& Grad) const
{
switch (typ) {
@@ -221,19 +277,39 @@ void IntSurf_Quadric::ValAndGrad (const gp_Pnt& P,
Dist = dist;
Grad=D1u.Crossed(D1v);
if(ax3direc==Standard_False) {
Grad.Reverse();
Grad.Reverse();
}
//-- lbr le 7 mars 96
//-- Si le gardient est nul, on est sur l axe
//-- et dans ce cas dist vaut 0
//-- On peut donc renvoyer une valeur quelconque.
if( Grad.X() > 1e-13
|| Grad.Y() > 1e-13
|| Grad.Z() > 1e-13) {
Grad.Normalize();
|| Grad.Y() > 1e-13
|| Grad.Z() > 1e-13) {
Grad.Normalize();
}
}
break;
case GeomAbs_Torus:
{
gp_Pnt O, Pp, PT;
//
O = ax3.Location();
gp_Vec OZ (ax3.Direction());
Pp = P.Translated(OZ.Multiplied(-(gp_Vec(O,P).Dot(ax3.Direction()))));
//
gp_Dir DOPp = (O.SquareDistance(Pp) < 1e-14) ?
ax3.XDirection() : gp_Dir(gp_Vec(O, Pp));
PT.SetXYZ(O.XYZ() + DOPp.XYZ()*prm1);
//
Dist = P.Distance(PT) - prm2;
//
Grad.SetXYZ(P.XYZ()-PT.XYZ());
Standard_Real N = Grad.Magnitude();
if(N>1e-14) { Grad.Divide(N); }
else { Grad.SetCoord(0., 0., 0.); }
}
break;
default:
{}
break;
@@ -241,7 +317,7 @@ void IntSurf_Quadric::ValAndGrad (const gp_Pnt& P,
}
// ============================================================
gp_Pnt IntSurf_Quadric::Value(const Standard_Real U,
const Standard_Real V) const
const Standard_Real V) const
{
switch (typ) {
@@ -253,6 +329,8 @@ gp_Pnt IntSurf_Quadric::Value(const Standard_Real U,
return ElSLib::SphereValue(U,V,ax3,prm1);
case GeomAbs_Cone:
return ElSLib::ConeValue(U,V,ax3,prm1,prm2);
case GeomAbs_Torus:
return ElSLib::TorusValue(U,V,ax3,prm1,prm2);
default:
{
gp_Pnt p(0,0,0);
@@ -265,10 +343,10 @@ gp_Pnt IntSurf_Quadric::Value(const Standard_Real U,
}
// ============================================================
void IntSurf_Quadric::D1(const Standard_Real U,
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
const Standard_Real V,
gp_Pnt& P,
gp_Vec& D1U,
gp_Vec& D1V) const
{
switch (typ) {
case GeomAbs_Plane:
@@ -283,6 +361,9 @@ void IntSurf_Quadric::D1(const Standard_Real U,
case GeomAbs_Cone:
ElSLib::ConeD1(U,V,ax3,prm1,prm2,P,D1U,D1V);
break;
case GeomAbs_Torus:
ElSLib::TorusD1(U,V,ax3,prm1,prm2,P,D1U,D1V);
break;
default:
{
}
@@ -291,9 +372,9 @@ void IntSurf_Quadric::D1(const Standard_Real U,
}
// ============================================================
gp_Vec IntSurf_Quadric::DN(const Standard_Real U,
const Standard_Real V,
const Standard_Integer Nu,
const Standard_Integer Nv) const
const Standard_Real V,
const Standard_Integer Nu,
const Standard_Integer Nv) const
{
switch (typ) {
case GeomAbs_Plane:
@@ -304,6 +385,8 @@ gp_Vec IntSurf_Quadric::DN(const Standard_Real U,
return ElSLib::SphereDN(U,V,ax3,prm1,Nu,Nv);
case GeomAbs_Cone:
return ElSLib::ConeDN(U,V,ax3,prm1,prm2,Nu,Nv);
case GeomAbs_Torus:
return ElSLib::TorusDN(U,V,ax3,prm1,prm2,Nu,Nv);
default:
{
gp_Vec v(0,0,0);
@@ -316,7 +399,7 @@ gp_Vec IntSurf_Quadric::DN(const Standard_Real U,
}
// ============================================================
gp_Vec IntSurf_Quadric::Normale(const Standard_Real U,
const Standard_Real V) const
const Standard_Real V) const
{
switch (typ) {
case GeomAbs_Plane:
@@ -334,11 +417,13 @@ gp_Vec IntSurf_Quadric::Normale(const Standard_Real U,
gp_Vec D1u,D1v;
ElSLib::ConeD1(U,V,ax3,prm1,prm2,P,D1u,D1v);
if(D1u.Magnitude()<0.0000001) {
gp_Vec Vn(0.0,0.0,0.0);
return(Vn);
gp_Vec Vn(0.0,0.0,0.0);
return(Vn);
}
return(D1u.Crossed(D1v));
}
case GeomAbs_Torus:
return Normale(Value(U,V));
default:
{
gp_Vec v(0,0,0);
@@ -361,30 +446,47 @@ gp_Vec IntSurf_Quadric::Normale (const gp_Pnt& P) const
case GeomAbs_Cylinder:
{
if(ax3direc) {
return lin.Normal(P).Direction();
return lin.Normal(P).Direction();
}
else {
gp_Dir D(lin.Normal(P).Direction());
D.Reverse();
return(D);
gp_Dir D(lin.Normal(P).Direction());
D.Reverse();
return(D);
}
}
case GeomAbs_Sphere:
{
if(ax3direc) {
gp_Vec ax3P(ax3.Location(),P);
return gp_Dir(ax3P);
gp_Vec ax3P(ax3.Location(),P);
return gp_Dir(ax3P);
}
else {
gp_Vec Pax3(P,ax3.Location());
return gp_Dir(Pax3);
gp_Vec Pax3(P,ax3.Location());
return gp_Dir(Pax3);
}
}
case GeomAbs_Cone:
{
Standard_Real U,V;
ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
return Normale(U,V);;
return Normale(U,V);
}
case GeomAbs_Torus:
{
gp_Pnt O, Pp, PT;
//
O = ax3.Location();
gp_Vec OZ (ax3.Direction());
Pp = P.Translated(OZ.Multiplied(-(gp_Vec(O,P).Dot(ax3.Direction()))));
//
gp_Dir DOPp = (O.SquareDistance(Pp) < 1e-14) ?
ax3.XDirection() : gp_Dir(gp_Vec(O, Pp));
PT.SetXYZ(O.XYZ() + DOPp.XYZ()*prm1);
if (PT.SquareDistance(P) < 1e-14) {
return gp_Dir(OZ);
}
gp_Dir aD(ax3direc ? gp_Vec(PT, P) : gp_Vec(P, PT));
return aD;
}
default:
{
@@ -395,8 +497,8 @@ gp_Vec IntSurf_Quadric::Normale (const gp_Pnt& P) const
}
// ============================================================
void IntSurf_Quadric::Parameters (const gp_Pnt& P,
Standard_Real& U,
Standard_Real& V) const
Standard_Real& U,
Standard_Real& V) const
{
switch (typ) {
case GeomAbs_Plane:
@@ -409,12 +511,12 @@ void IntSurf_Quadric::Parameters (const gp_Pnt& P,
ElSLib::SphereParameters(ax3,prm1,P,U,V);
break;
case GeomAbs_Cone:
{
ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
}
ElSLib::ConeParameters(ax3,prm1,prm2,P,U,V);
break;
case GeomAbs_Torus:
ElSLib::TorusParameters(ax3,prm1,prm2,P,U,V);
break;
default:
{}
break;
}
}

View File

@@ -58,4 +58,9 @@ inline gp_Cone IntSurf_Quadric::Cone () const {
return gp_Cone(ax3,prm2,prm1);
}
inline gp_Torus IntSurf_Quadric::Torus () const {
return gp_Torus(ax3, prm1, prm2);
}