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:
parent
1220d98e7a
commit
14ba0bbad7
@ -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();
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//=======================================================================
|
//=======================================================================
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
23
tests/v3d/dimensions/bug32351
Normal file
23
tests/v3d/dimensions/bug32351
Normal 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
|
Loading…
x
Reference in New Issue
Block a user