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

0032351: Visualization, PrsDim_LengthDimension - add NULL checks for handling non-Line curves

Added several missing NULL-checks.
Reduced restrictions on building Edge-Edge and Edge-Vertex length dimension.
Added empty constructor for more straightforward initialization from vdimension command.
This commit is contained in:
kgv 2021-05-10 09:05:11 +03:00 committed by bugmaster
parent 1220d98e7a
commit 14ba0bbad7
6 changed files with 222 additions and 197 deletions

View File

@ -233,21 +233,15 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theEdge,
gp_Pnt& theLastPnt, gp_Pnt& theLastPnt,
Standard_Boolean& theIsInfinite) Standard_Boolean& theIsInfinite)
{ {
Standard_Real aFirst, aLast;
BRepAdaptor_Curve anAdaptor (theEdge); BRepAdaptor_Curve anAdaptor (theEdge);
theCurve = Handle(Geom_Curve)::DownCast (anAdaptor.Curve().Curve()->Transformed (anAdaptor.Trsf()));
theCurve = Handle(Geom_Curve)::DownCast
(anAdaptor.Curve().Curve()->Transformed (anAdaptor.Trsf()));
if (theCurve.IsNull()) if (theCurve.IsNull())
{ {
return Standard_False; return Standard_False;
} }
aFirst = anAdaptor.FirstParameter(); const Standard_Real aFirst = anAdaptor.FirstParameter();
aLast = anAdaptor.LastParameter(); const Standard_Real aLast = anAdaptor.LastParameter();
theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast)); theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
@ -288,18 +282,16 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theEdge,
return Standard_False; return Standard_False;
} }
Standard_Real aFirst, aLast;
BRepAdaptor_Curve aCurveAdaptor (theEdge); BRepAdaptor_Curve aCurveAdaptor (theEdge);
theCurve = Handle(Geom_Curve)::DownCast (aCurveAdaptor.Curve().Curve()->Transformed (aCurveAdaptor.Trsf())); theCurve = Handle(Geom_Curve)::DownCast (aCurveAdaptor.Curve().Curve()->Transformed (aCurveAdaptor.Trsf()));
aFirst = aCurveAdaptor.FirstParameter();
aLast = aCurveAdaptor.LastParameter();
if (theCurve.IsNull()) if (theCurve.IsNull())
{ {
return Standard_False; return Standard_False;
} }
theExtCurve = theCurve; theExtCurve = theCurve;
const Standard_Real aFirst = aCurveAdaptor.FirstParameter();
const Standard_Real aLast = aCurveAdaptor.LastParameter();
theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast)); theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast));
// Checks that the projected curve is not in the plane. // Checks that the projected curve is not in the plane.
@ -309,17 +301,14 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theEdge,
theExtCurve = Handle(Geom_TrimmedCurve)::DownCast (theExtCurve)->BasisCurve(); theExtCurve = Handle(Geom_TrimmedCurve)::DownCast (theExtCurve)->BasisCurve();
} }
if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Line))) if (Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theExtCurve))
{ {
Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theExtCurve);
theIsOnPlane = thePlane->Pln().Contains (aLine->Lin(), theIsOnPlane = thePlane->Pln().Contains (aLine->Lin(),
Precision::Confusion(), Precision::Confusion(),
Precision::Angular()); Precision::Angular());
} }
else if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) else if (Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast (theExtCurve))
{ {
Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast (theExtCurve);
gp_Ax3 aCircPos (aCircle->Position()); gp_Ax3 aCircPos (aCircle->Position());
theIsOnPlane = aCircPos.IsCoplanar (thePlane->Pln().Position(), theIsOnPlane = aCircPos.IsCoplanar (thePlane->Pln().Position(),
Precision::Confusion(), Precision::Confusion(),
@ -335,29 +324,24 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theEdge,
thePlane->Pln().Axis().Direction(), thePlane->Pln().Axis().Direction(),
Standard_False); Standard_False);
if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line))) if (Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve))
{ {
Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve);
if (!theIsInfinite) if (!theIsInfinite)
{ {
theFirstPnt = ElCLib::Value (aFirst, aLine->Lin()); theFirstPnt = ElCLib::Value (aFirst, aLine->Lin());
theLastPnt = ElCLib::Value (aLast, aLine->Lin()); theLastPnt = ElCLib::Value (aLast, aLine->Lin());
} }
} }
else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) else if (Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve))
{ {
Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve);
theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ()); theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ());
theLastPnt = ElCLib::Value (aLast, aCirc->Circ()); theLastPnt = ElCLib::Value (aLast, aCirc->Circ());
} }
else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse))) else if (Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve))
{ {
Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve); theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips());
theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips()); }
theLastPnt = ElCLib::Value (aLast, anEllipse->Elips());
}
else else
{ {
return Standard_False; return Standard_False;
@ -390,13 +374,8 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
theFirstCurve = BRep_Tool::Curve (theFirstEdge, aFirstEdgeLoc, aFirst1, aLast1); theFirstCurve = BRep_Tool::Curve (theFirstEdge, aFirstEdgeLoc, aFirst1, aLast1);
theSecondCurve = BRep_Tool::Curve (theSecondEdge, aSecondEdgeLoc, aFirst2, aLast2); theSecondCurve = BRep_Tool::Curve (theSecondEdge, aSecondEdgeLoc, aFirst2, aLast2);
if (theFirstCurve.IsNull()
if (theFirstCurve.IsNull()) || theSecondCurve.IsNull())
{
return Standard_False;
}
if (theSecondCurve.IsNull())
{ {
return Standard_False; return Standard_False;
} }
@ -417,33 +396,25 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
thePlane->Pln().Axis().Direction(), thePlane->Pln().Axis().Direction(),
Standard_False); Standard_False);
theSecondCurve = GeomProjLib::ProjectOnPlane (theSecondCurve, thePlane, theSecondCurve = GeomProjLib::ProjectOnPlane (theSecondCurve, thePlane,
thePlane->Pln().Axis().Direction(), thePlane->Pln().Axis().Direction(),
Standard_False); Standard_False);
if (theFirstCurve->IsInstance (STANDARD_TYPE(Geom_TrimmedCurve))) if (theFirstCurve->IsInstance (STANDARD_TYPE(Geom_TrimmedCurve)))
{ {
theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve(); theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve();
} }
if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve)))
{ {
theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve(); theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve();
} }
if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Line))) if (Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theFirstCurve))
{ {
Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theFirstCurve);
theFirstPnt1 = ElCLib::Value (aFirst1, aLine->Lin()); theFirstPnt1 = ElCLib::Value (aFirst1, aLine->Lin());
theLastPnt1 = ElCLib::Value (aLast1, aLine->Lin()); theLastPnt1 = ElCLib::Value (aLast1, aLine->Lin());
} }
else if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) else if (Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theFirstCurve))
{ {
Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theFirstCurve);
theFirstPnt1 = ElCLib::Value (aFirst1, aCirc->Circ()); theFirstPnt1 = ElCLib::Value (aFirst1, aCirc->Circ());
theLastPnt1 = ElCLib::Value (aLast1, aCirc->Circ()); theLastPnt1 = ElCLib::Value (aLast1, aCirc->Circ());
} }
@ -452,17 +423,13 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
return Standard_False; return Standard_False;
} }
if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Line))) if (Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theSecondCurve))
{ {
Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theSecondCurve);
theFirstPnt2 = ElCLib::Value (aFirst2, aLine->Lin()); theFirstPnt2 = ElCLib::Value (aFirst2, aLine->Lin());
theLastPnt2 = ElCLib::Value (aLast2, aLine->Lin()); theLastPnt2 = ElCLib::Value (aLast2, aLine->Lin());
} }
else if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) else if (Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theSecondCurve))
{ {
Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theSecondCurve);
theFirstPnt2 = ElCLib::Value (aFirst2, aCirc->Circ()); theFirstPnt2 = ElCLib::Value (aFirst2, aCirc->Circ());
theLastPnt2 = ElCLib::Value (aLast2, aCirc->Circ()); theLastPnt2 = ElCLib::Value (aLast2, aCirc->Circ());
} }
@ -489,62 +456,60 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
Standard_Boolean& theIsInfinite1, Standard_Boolean& theIsInfinite1,
Standard_Boolean& theIsInfinite2) Standard_Boolean& theIsInfinite2)
{ {
theIsInfinite1 = theIsInfinite2 = Standard_False; theIsInfinite1 = theIsInfinite2 = Standard_False;
if (!PrsDim::ComputeGeometry (theFirstEdge, theFirstCurve, theFirstPnt1, theLastPnt1, theIsInfinite1))
if (!PrsDim::ComputeGeometry (theFirstEdge, theFirstCurve,theFirstPnt1, theLastPnt1, theIsInfinite1)) {
{ return Standard_False;
return Standard_False; }
} if (!PrsDim::ComputeGeometry (theSecondEdge, theSecondCurve, theFirstPnt2, theLastPnt2, theIsInfinite2))
{
if (!PrsDim::ComputeGeometry (theSecondEdge, theSecondCurve,theFirstPnt2, theLastPnt2, theIsInfinite2)) return Standard_False;
{ }
return Standard_False;
}
if (theIsInfinite1 || theIsInfinite2) if (theIsInfinite1 || theIsInfinite2)
{ {
if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()) if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()
&& theFirstCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
{
gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin();
gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin();
if (theIsInfinite1)
{ {
gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin(); theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1);
gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin(); theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1);
}
else if (theIsInfinite2)
{
theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2);
}
}
else
{
if (theIsInfinite1 && !theIsInfinite2)
{
GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt2, theFirstCurve);
theFirstPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter());
if (theIsInfinite1) aProjector.Init (theLastPnt2, theFirstCurve);
{ theLastPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter());
theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1); }
theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1); else if (!theIsInfinite1 && theIsInfinite2)
} {
else if (theIsInfinite2) GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt1, theSecondCurve);
{ theFirstPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter());
theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2);
theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2); aProjector.Init (theLastPnt1, theSecondCurve);
} theLastPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter());
} }
else else
{ {
if (theIsInfinite1 && !theIsInfinite2) return Standard_False;
{
GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt2, theFirstCurve);
theFirstPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
aProjector.Init (theLastPnt2, theFirstCurve);
theLastPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ());
}
else if (!theIsInfinite1 && theIsInfinite2)
{
GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt1, theSecondCurve);
theFirstPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
aProjector.Init (theLastPnt1, theSecondCurve);
theLastPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ());
}
else
{
return Standard_False;
}
} }
}
} }
return Standard_True; return Standard_True;
} }
//======================================================================= //=======================================================================
@ -553,7 +518,7 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
// and the 'right' geometry of the edges if one doesn't // and the 'right' geometry of the edges if one doesn't
// belong to the current working plane. // belong to the current working plane.
// There may be only one curve that can't belong to the // There may be only one curve that can't belong to the
// current working plane ( attachement constraint) // current working plane (attachment constraint)
// if the 2 edges belong to the current WP, <WhatProj> = 0 // if the 2 edges belong to the current WP, <WhatProj> = 0
// //
// indexExt = 0 2 edges are in the current wp // indexExt = 0 2 edges are in the current wp
@ -619,7 +584,7 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
Handle(Geom_Curve) aSecondSaved = theSecondCurve; Handle(Geom_Curve) aSecondSaved = theSecondCurve;
// Checks that the projected curve is not in the plane // Checks that the projected curve is not in the plane
Standard_Boolean isFirstOnPlane,isSecondOnPlane; Standard_Boolean isFirstOnPlane, isSecondOnPlane;
if ((!ComputeGeomCurve (theFirstCurve, aFirst1, aLast1, theFirstPnt1, theLastPnt1, thePlane, isFirstOnPlane)) if ((!ComputeGeomCurve (theFirstCurve, aFirst1, aLast1, theFirstPnt1, theLastPnt1, thePlane, isFirstOnPlane))
|| (!ComputeGeomCurve( theSecondCurve, aFirst2, aLast2, theFirstPnt2, theLastPnt2, thePlane,isSecondOnPlane))) || (!ComputeGeomCurve( theSecondCurve, aFirst2, aLast2, theFirstPnt2, theLastPnt2, thePlane,isSecondOnPlane)))
@ -644,7 +609,8 @@ Standard_Boolean PrsDim::ComputeGeometry (const TopoDS_Edge& theFirstEdge,
if (theIsInfinite1 || theIsInfinite2) if (theIsInfinite1 || theIsInfinite2)
{ {
if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()) if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()
&& theFirstCurve->IsInstance (STANDARD_TYPE (Geom_Line)))
{ {
gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin(); gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin();
gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin(); gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin();

View File

@ -29,6 +29,7 @@
#include <gce_MakePln.hxx> #include <gce_MakePln.hxx>
#include <Geom_TrimmedCurve.hxx> #include <Geom_TrimmedCurve.hxx>
#include <GeomAPI_ExtremaCurveCurve.hxx> #include <GeomAPI_ExtremaCurveCurve.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <GeomAPI_ExtremaSurfaceSurface.hxx> #include <GeomAPI_ExtremaSurfaceSurface.hxx>
#include <Geom_Curve.hxx> #include <Geom_Curve.hxx>
#include <Geom_Line.hxx> #include <Geom_Line.hxx>
@ -37,6 +38,17 @@
IMPLEMENT_STANDARD_RTTIEXT(PrsDim_LengthDimension, PrsDim_Dimension) IMPLEMENT_STANDARD_RTTIEXT(PrsDim_LengthDimension, PrsDim_Dimension)
//=======================================================================
//function : Constructor
//purpose :
//=======================================================================
PrsDim_LengthDimension::PrsDim_LengthDimension()
: PrsDim_Dimension (PrsDim_KOD_LENGTH),
myHasCustomDirection (Standard_False)
{
SetFlyout (15.0);
}
//======================================================================= //=======================================================================
//function : Constructor //function : Constructor
//purpose : Dimension between two faces //purpose : Dimension between two faces
@ -354,28 +366,10 @@ Standard_Boolean PrsDim_LengthDimension::InitTwoEdgesLength (const TopoDS_Edge&
const TopoDS_Edge& theSecondEdge, const TopoDS_Edge& theSecondEdge,
gp_Dir& theDirAttach) gp_Dir& theDirAttach)
{ {
BRepAdaptor_Curve aFirstCurveAdapt (theFirstEdge); Handle(Geom_Curve) aFirstCurve, aSecondCurve;
if (aFirstCurveAdapt.GetType() != GeomAbs_Line) gp_Pnt aPoint11, aPoint12, aPoint21, aPoint22;
{
return Standard_False;
}
BRepAdaptor_Curve aSecondCurveAdapt (theSecondEdge);
if (aSecondCurveAdapt.GetType() != GeomAbs_Line)
{
return Standard_False;
}
Handle(Geom_Curve) aFirstCurve;
Handle(Geom_Curve) aSecondCurve;
gp_Pnt aPoint11 (gp::Origin());
gp_Pnt aPoint12 (gp::Origin());
gp_Pnt aPoint21 (gp::Origin());
gp_Pnt aPoint22 (gp::Origin());
Standard_Boolean isFirstInfinite = Standard_False; Standard_Boolean isFirstInfinite = Standard_False;
Standard_Boolean isSecondInfinite = Standard_False; Standard_Boolean isSecondInfinite = Standard_False;
if (!PrsDim::ComputeGeometry (theFirstEdge, theSecondEdge, if (!PrsDim::ComputeGeometry (theFirstEdge, theSecondEdge,
aFirstCurve, aSecondCurve, aFirstCurve, aSecondCurve,
aPoint11, aPoint12, aPoint11, aPoint12,
@ -388,51 +382,79 @@ Standard_Boolean PrsDim_LengthDimension::InitTwoEdgesLength (const TopoDS_Edge&
const Handle(Geom_Line) aFirstLine = Handle(Geom_Line)::DownCast (aFirstCurve); const Handle(Geom_Line) aFirstLine = Handle(Geom_Line)::DownCast (aFirstCurve);
const Handle(Geom_Line) aSecondLine = Handle(Geom_Line)::DownCast (aSecondCurve); const Handle(Geom_Line) aSecondLine = Handle(Geom_Line)::DownCast (aSecondCurve);
if (!aFirstLine.IsNull()
if (!aFirstLine->Lin().Direction().IsParallel (aSecondLine->Lin().Direction(),Precision::Angular())) && !aSecondLine.IsNull())
{ {
return Standard_False; if (!aFirstLine->Lin().Direction().IsParallel (aSecondLine->Lin().Direction(), Precision::Angular()))
}
theDirAttach = aFirstLine->Lin().Direction();
gp_Pnt aPoint;
if (!isFirstInfinite)
{
if (PrsDim::Nearest (aSecondCurve, aPoint11, aPoint21, aPoint22, aPoint))
{ {
myFirstPoint = aPoint11; return Standard_False;
mySecondPoint = aPoint;
return IsValidPoints (myFirstPoint, mySecondPoint);
} }
else if (PrsDim::Nearest (aSecondCurve, aPoint12, aPoint21, aPoint22, aPoint))
{
myFirstPoint = aPoint12;
mySecondPoint = aPoint;
return IsValidPoints (myFirstPoint, mySecondPoint);
}
}
if (!isSecondInfinite) theDirAttach = aFirstLine->Lin().Direction();
{
if (PrsDim::Nearest (aFirstCurve, aPoint21, aPoint11, aPoint12, aPoint)) gp_Pnt aPoint;
if (!isFirstInfinite)
{ {
myFirstPoint = aPoint; if (PrsDim::Nearest (aSecondCurve, aPoint11, aPoint21, aPoint22, aPoint))
mySecondPoint = aPoint21; {
return IsValidPoints (myFirstPoint, mySecondPoint); myFirstPoint = aPoint11;
mySecondPoint = aPoint;
return IsValidPoints (myFirstPoint, mySecondPoint);
}
else if (PrsDim::Nearest (aSecondCurve, aPoint12, aPoint21, aPoint22, aPoint))
{
myFirstPoint = aPoint12;
mySecondPoint = aPoint;
return IsValidPoints (myFirstPoint, mySecondPoint);
}
} }
if (PrsDim::Nearest (aFirstCurve, aPoint22, aPoint11, aPoint12, aPoint))
if (!isSecondInfinite)
{ {
myFirstPoint = aPoint; if (PrsDim::Nearest (aFirstCurve, aPoint21, aPoint11, aPoint12, aPoint))
mySecondPoint = aPoint22; {
return IsValidPoints (myFirstPoint, mySecondPoint); myFirstPoint = aPoint;
mySecondPoint = aPoint21;
return IsValidPoints (myFirstPoint, mySecondPoint);
}
if (PrsDim::Nearest (aFirstCurve, aPoint22, aPoint11, aPoint12, aPoint))
{
myFirstPoint = aPoint;
mySecondPoint = aPoint22;
return IsValidPoints (myFirstPoint, mySecondPoint);
}
} }
} }
GeomAPI_ExtremaCurveCurve anExtrema (aFirstCurve, aSecondCurve); GeomAPI_ExtremaCurveCurve anExtrema (aFirstCurve, aSecondCurve);
if (anExtrema.NbExtrema() == 0)
{
return false;
}
anExtrema.NearestPoints (myFirstPoint, mySecondPoint); anExtrema.NearestPoints (myFirstPoint, mySecondPoint);
return IsValidPoints (myFirstPoint, mySecondPoint); if (!IsValidPoints (myFirstPoint, mySecondPoint))
{
return false;
}
if (aFirstLine.IsNull()
|| aSecondLine.IsNull())
{
Standard_Real aParam1 = 0.0, aParam2 = 0.0;
anExtrema.LowerDistanceParameters (aParam1, aParam2);
BRepAdaptor_Curve aCurveAdaptor (theFirstEdge);
gp_Pnt aPoint;
gp_Vec aDir;
aCurveAdaptor.D1 (aParam1, aPoint, aDir);
if (aDir.SquareMagnitude() <= gp::Resolution())
{
return false;
}
theDirAttach = aDir;
}
return true;
} }
//======================================================================= //=======================================================================
@ -444,10 +466,8 @@ Standard_Boolean PrsDim_LengthDimension::InitEdgeVertexLength (const TopoDS_Edge
gp_Dir& theEdgeDir, gp_Dir& theEdgeDir,
Standard_Boolean isInfinite) Standard_Boolean isInfinite)
{ {
gp_Pnt anEdgePoint1 (gp::Origin()); gp_Pnt anEdgePoint1, anEdgePoint2;
gp_Pnt anEdgePoint2 (gp::Origin());
Handle(Geom_Curve) aCurve; Handle(Geom_Curve) aCurve;
if (!PrsDim::ComputeGeometry (theEdge, aCurve, anEdgePoint1, anEdgePoint2, isInfinite)) if (!PrsDim::ComputeGeometry (theEdge, aCurve, anEdgePoint1, anEdgePoint2, isInfinite))
{ {
return Standard_False; return Standard_False;
@ -455,15 +475,39 @@ Standard_Boolean PrsDim_LengthDimension::InitEdgeVertexLength (const TopoDS_Edge
myFirstPoint = BRep_Tool::Pnt (theVertex); myFirstPoint = BRep_Tool::Pnt (theVertex);
Handle(Geom_Line) aGeomLine (Handle(Geom_Line)::DownCast (aCurve)); if (Handle(Geom_Line) aGeomLine = Handle(Geom_Line)::DownCast (aCurve))
const gp_Lin& aLin = aGeomLine->Lin(); {
const gp_Lin aLin = aGeomLine->Lin();
// Get direction of edge to build plane automatically. // Get direction of edge to build plane automatically.
theEdgeDir = aLin.Direction(); theEdgeDir = aLin.Direction();
mySecondPoint = PrsDim::Nearest (aLin, myFirstPoint); mySecondPoint = PrsDim::Nearest (aLin, myFirstPoint);
return IsValidPoints (myFirstPoint, mySecondPoint);
}
return IsValidPoints (myFirstPoint, mySecondPoint); GeomAPI_ProjectPointOnCurve anExtrema (myFirstPoint, aCurve);
if (anExtrema.NbPoints() == 0)
{
return false;
}
mySecondPoint = anExtrema.NearestPoint();
if (!IsValidPoints (myFirstPoint, mySecondPoint))
{
return false;
}
BRepAdaptor_Curve aCurveAdaptor (theEdge);
gp_Pnt aPoint;
gp_Vec aDir;
aCurveAdaptor.D1 (anExtrema.LowerDistanceParameter(), aPoint, aDir);
if (aDir.SquareMagnitude() <= gp::Resolution())
{
return false;
}
theEdgeDir = aDir;
return true;
} }
//======================================================================= //=======================================================================

View File

@ -49,6 +49,10 @@ class PrsDim_LengthDimension : public PrsDim_Dimension
DEFINE_STANDARD_RTTIEXT(PrsDim_LengthDimension, PrsDim_Dimension) DEFINE_STANDARD_RTTIEXT(PrsDim_LengthDimension, PrsDim_Dimension)
public: public:
//! Construct an empty length dimension.
//! @sa SetMeasuredGeometry(), SetMeasuredShapes() for initialization.
Standard_EXPORT PrsDim_LengthDimension();
//! Construct length dimension between face and edge. //! Construct length dimension between face and edge.
//! Here dimension can be built without user-defined plane. //! Here dimension can be built without user-defined plane.
//! @param theFace [in] the face (first shape). //! @param theFace [in] the face (first shape).
@ -88,23 +92,23 @@ public:
public: public:
//! @return first attachement point. //! @return first attachment point.
const gp_Pnt& FirstPoint() const { return myFirstPoint; } const gp_Pnt& FirstPoint() const { return myFirstPoint; }
//! @return second attachement point. //! @return second attachment point.
const gp_Pnt& SecondPoint() const { return mySecondPoint; } const gp_Pnt& SecondPoint() const { return mySecondPoint; }
//! @return first attachement shape. //! @return first attachment shape.
const TopoDS_Shape& FirstShape() const { return myFirstShape; } const TopoDS_Shape& FirstShape() const { return myFirstShape; }
//! @return second attachement shape. //! @return second attachment shape.
const TopoDS_Shape& SecondShape() const { return mySecondShape; } const TopoDS_Shape& SecondShape() const { return mySecondShape; }
public: public:
//! Measure distance between two points. //! Measure distance between two points.
//! The dimension will become invalid if the new distance between //! The dimension will become invalid if the new distance between
//! attachement points is less than Precision::Confusion(). //! attachment points is less than Precision::Confusion().
//! @param theFirstPoint [in] the first point. //! @param theFirstPoint [in] the first point.
//! @param theSecondPoint [in] the second point. //! @param theSecondPoint [in] the second point.
//! @param thePlane [in] the user-defined plane //! @param thePlane [in] the user-defined plane
@ -208,8 +212,7 @@ protected:
//! Auxiliary method for InitTwoShapesPoints() //! Auxiliary method for InitTwoShapesPoints()
//! in case of the distance between edge and vertex. //! in case of the distance between edge and vertex.
//! Finds the point on the edge that is the closest one to <theVertex>. //! Finds the point on the edge that is the closest one to <theVertex>.
//! @param theEdgeDir [out] is the direction on the edge to build //! @param theEdgeDir [out] is the direction on the edge to build automatic plane.
//! automatical plane.
Standard_EXPORT Standard_Boolean InitEdgeVertexLength (const TopoDS_Edge& theEdge, Standard_EXPORT Standard_Boolean InitEdgeVertexLength (const TopoDS_Edge& theEdge,
const TopoDS_Vertex& theVertex, const TopoDS_Vertex& theVertex,
gp_Dir& theEdgeDir, gp_Dir& theEdgeDir,
@ -220,9 +223,8 @@ protected:
//! The first attachment point is first parameter point from <theEdge>. //! The first attachment point is first parameter point from <theEdge>.
//! Find the second attachment point which belongs to <theFace> //! Find the second attachment point which belongs to <theFace>
//! Iterate over the edges of the face and find the closest point according //! Iterate over the edges of the face and find the closest point according
//! to finded point on edge. //! to found point on edge.
//! @param theEdgeDir [out] is the direction on the edge to build //! @param theEdgeDir [out] is the direction on the edge to build automatic plane.
//! automatical plane.
Standard_EXPORT Standard_Boolean InitEdgeFaceLength (const TopoDS_Edge& theEdge, Standard_EXPORT Standard_Boolean InitEdgeFaceLength (const TopoDS_Edge& theEdge,
const TopoDS_Face& theFace, const TopoDS_Face& theFace,
gp_Dir& theEdgeDir); gp_Dir& theEdgeDir);
@ -236,7 +238,7 @@ protected:
//! Initialization of two attach points in case of one owner shape. //! Initialization of two attach points in case of one owner shape.
Standard_EXPORT Standard_Boolean InitOneShapePoints (const TopoDS_Shape& theShape); Standard_EXPORT Standard_Boolean InitOneShapePoints (const TopoDS_Shape& theShape);
private: protected:
gp_Pnt myFirstPoint; gp_Pnt myFirstPoint;
gp_Pnt mySecondPoint; gp_Pnt mySecondPoint;

View File

@ -770,26 +770,9 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
} }
// Face-Face case // Face-Face case
if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_FACE) Handle(PrsDim_LengthDimension) aLenDim = new PrsDim_LengthDimension();
if (isPlaneCustom)
{ {
aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape1), TopoDS::Face (aShape2));
}
else if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_EDGE)
{
aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape1), TopoDS::Edge (aShape2));
}
else if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_FACE)
{
aDim = new PrsDim_LengthDimension (TopoDS::Face (aShape2), TopoDS::Edge (aShape1));
}
else
{
if (!isPlaneCustom)
{
Message::SendFail ("Error: can not build dimension without working plane.");
return 1;
}
// Vertex-Vertex case
if (aShape1.ShapeType() == TopAbs_VERTEX) if (aShape1.ShapeType() == TopAbs_VERTEX)
{ {
aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1))); aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1)));
@ -798,9 +781,16 @@ static int VDimBuilder (Draw_Interpretor& /*theDi*/,
{ {
aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2))); aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2)));
} }
aLenDim->SetCustomPlane (aWorkingPlane);
aDim = new PrsDim_LengthDimension (aShape1, aShape2, aWorkingPlane);
} }
else if (aShape1.ShapeType() == TopAbs_VERTEX
&& aShape2.ShapeType() == TopAbs_VERTEX)
{
Message::SendFail ("Error: can not build dimension without working plane");
return 1;
}
aLenDim->SetMeasuredShapes (aShape1, aShape2);
aDim = aLenDim;
} }
else else
{ {

View File

@ -11,7 +11,7 @@ vclear
vaxo vaxo
explode b F explode b F
vdisplay b_1 b_2 vdisplay b_1 b_2
vdimension len -length -shapes b_1 b_2 -plane zox vdimension len -length -shapes b_1 b_2
vfit vfit
vdump ${imagedir}/${casename}.png vdump ${imagedir}/${casename}.png

View File

@ -0,0 +1,23 @@
puts "========"
puts "0032351: Visualization, PrsDim_LengthDimension - add NULL checks for handling non-Line curves"
puts "========"
pload MODELING VISUALIZATION
box b 200 0 0 100 200 300
pcylinder c 100 200
vinit View1
vdisplay -dispMode 0 b c
vfit
explode b V
explode c E
vdisplay c_1 b_1
vdimension d1 -length -shapes c_1 b_1 -plane zox
explode b E
explode c E
vdisplay c_1 b_3
vdimension d2 -length -shapes c_1 b_3
vfit
vdump $imagedir/${casename}.png