mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-01 17:36:21 +03:00
0025209: Draw Harness - add command 'vnormals' and extend command 'normals' to show variable number of normals
This commit is contained in:
parent
c0a1a35fac
commit
68ef63f9f3
@ -31,6 +31,7 @@
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <GProp.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <Standard.hxx>
|
||||
@ -1118,73 +1119,124 @@ static Standard_Integer check(Draw_Interpretor& ,
|
||||
//=======================================================================
|
||||
// normals
|
||||
//=======================================================================
|
||||
|
||||
static Standard_Integer normals(Draw_Interpretor& di,
|
||||
Standard_Integer n, const char** a)
|
||||
static Standard_Integer normals (Draw_Interpretor& theDI,
|
||||
Standard_Integer theArgNum,
|
||||
const char** theArgs)
|
||||
{
|
||||
if (n <= 1) return 1;
|
||||
Standard_Real l = 1.;
|
||||
if (n > 2)
|
||||
l = Draw::Atof(a[2]);
|
||||
if (theArgNum < 2)
|
||||
{
|
||||
std::cout << "Syntax error: wrong number of arguments!\n";
|
||||
theDI.PrintHelp (theArgs[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
TopoDS_Shape S = DBRep::Get(a[1]);
|
||||
if (S.IsNull()) return 1;
|
||||
TopoDS_Shape aShape = DBRep::Get (theArgs[1]);
|
||||
if (aShape.IsNull())
|
||||
{
|
||||
std::cout << "Error: shape with name " << theArgs[1] << " is not found\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Standard_Boolean toUseMesh = Standard_False;
|
||||
Standard_Real aLength = 10.0;
|
||||
Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
|
||||
for (Standard_Integer anArgIter = 2; anArgIter< theArgNum; ++anArgIter)
|
||||
{
|
||||
TCollection_AsciiString aParam (theArgs[anArgIter]);
|
||||
aParam.LowerCase();
|
||||
if (anArgIter == 2
|
||||
&& aParam.IsRealValue())
|
||||
{
|
||||
aLength = aParam.RealValue();
|
||||
if (Abs (aLength) <= gp::Resolution())
|
||||
{
|
||||
std::cout << "Syntax error: length should not be zero\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-usemesh"
|
||||
|| aParam == "-mesh")
|
||||
{
|
||||
toUseMesh = Standard_True;
|
||||
}
|
||||
else if (aParam == "-length"
|
||||
|| aParam == "-len")
|
||||
{
|
||||
++anArgIter;
|
||||
aLength = anArgIter < theArgNum ? Draw::Atof(theArgs[anArgIter]) : 0.0;
|
||||
if (Abs(aLength) <= gp::Resolution())
|
||||
{
|
||||
std::cout << "Syntax error: length should not be zero\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalongu"
|
||||
|| aParam == "-nbu")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
if (aNbAlongU < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlongU should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalongv"
|
||||
|| aParam == "-nbv")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongV = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
if (aNbAlongV < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlongV should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalong"
|
||||
|| aParam == "-nbuv")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongU = anArgIter< theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
aNbAlongV = aNbAlongU;
|
||||
if (aNbAlongU < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlong should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: unknwon argument '" << aParam << "'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
DBRep_WriteColorOrientation();
|
||||
|
||||
gp_Pnt P1,P2;
|
||||
gp_Vec V,V1,V2;
|
||||
Draw_Color col;
|
||||
|
||||
TopExp_Explorer ex(S,TopAbs_FACE);
|
||||
while (ex.More()) {
|
||||
|
||||
const TopoDS_Face& F = TopoDS::Face(ex.Current());
|
||||
|
||||
// find the center of the minmax
|
||||
BRepAdaptor_Surface SF(F);
|
||||
|
||||
Standard_Real u, v, x;
|
||||
|
||||
u = SF.FirstUParameter();
|
||||
x = SF.LastUParameter();
|
||||
if (Precision::IsInfinite(u))
|
||||
u = (Precision::IsInfinite(x)) ? 0. : x;
|
||||
else if (!Precision::IsInfinite(x))
|
||||
u = (u+x) / 2.;
|
||||
|
||||
v = SF.FirstVParameter();
|
||||
x = SF.LastVParameter();
|
||||
if (Precision::IsInfinite(v))
|
||||
v = (Precision::IsInfinite(x)) ? 0. : x;
|
||||
else if (!Precision::IsInfinite(x))
|
||||
v = (v+x) / 2.;
|
||||
|
||||
SF.D1(u,v,P1,V1,V2);
|
||||
V = V1.Crossed(V2);
|
||||
x = V.Magnitude();
|
||||
if (x > 1.e-10)
|
||||
V.Multiply(l/x);
|
||||
else {
|
||||
V.SetCoord(l/2.,0,0);
|
||||
di << "Null normal\n";
|
||||
}
|
||||
|
||||
P2 = P1;
|
||||
P2.Translate(V);
|
||||
|
||||
col = DBRep_ColorOrientation(F.Orientation());
|
||||
|
||||
Handle(Draw_Segment3D) seg = new Draw_Segment3D(P1,P2,col);
|
||||
dout << seg;
|
||||
|
||||
|
||||
ex.Next();
|
||||
NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > aNormals;
|
||||
if (toUseMesh)
|
||||
{
|
||||
DBRep_DrawableShape::addMeshNormals (aNormals, aShape, aLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBRep_DrawableShape::addSurfaceNormals (aNormals, aShape, aLength, aNbAlongU, aNbAlongV);
|
||||
}
|
||||
|
||||
for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormals); aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
const Draw_Color aColor = DBRep_ColorOrientation (aFaceIt.Key().Orientation());
|
||||
for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aNormalsIt (aFaceIt.Value()); aNormalsIt.More(); aNormalsIt.Next())
|
||||
{
|
||||
const std::pair<gp_Pnt, gp_Pnt>& aVec = aNormalsIt.Value();
|
||||
Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aVec.first, aVec.second, aColor);
|
||||
dout << aSeg;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Set
|
||||
//purpose :
|
||||
@ -1354,7 +1406,7 @@ void DBRep::BasicCommands(Draw_Interpretor& theCommands)
|
||||
theCommands.Add("treverse","treverse name1 name2 ...",__FILE__,orientation,g);
|
||||
theCommands.Add("complement","complement name1 name2 ...",__FILE__,orientation,g);
|
||||
theCommands.Add("invert","invert name, reverse subshapes",__FILE__,invert,g);
|
||||
theCommands.Add("normals","normals s (length = 10), disp normals",__FILE__,normals,g);
|
||||
theCommands.Add("normals","normals shape [Length {10}] [-NbAlongU {1}] [-NbAlongV {1}] [-UseMesh], display normals",__FILE__,normals,g);
|
||||
theCommands.Add("nbshapes",
|
||||
"\n nbshapes s - shows the number of sub-shapes in <s>;\n nbshapes s -t - shows the number of sub-shapes in <s> counting the same sub-shapes with different location as different sub-shapes.",
|
||||
__FILE__,nbshapes,g);
|
||||
|
@ -1174,3 +1174,161 @@ void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : addMeshNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean DBRep_DrawableShape::addMeshNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
|
||||
const TopoDS_Face& theFace,
|
||||
const Standard_Real theLength)
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
const Handle(Poly_Triangulation)& aTriangulation = BRep_Tool::Triangulation (theFace, aLoc);
|
||||
const Standard_Boolean hasNormals = aTriangulation->HasNormals();
|
||||
if (aTriangulation.IsNull()
|
||||
|| (!hasNormals && !aTriangulation->HasUVNodes()))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
|
||||
BRepAdaptor_Surface aSurface (theFace);
|
||||
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
|
||||
{
|
||||
gp_Pnt aP1 = aNodes (aNodeIter);
|
||||
if (!aLoc.IsIdentity())
|
||||
{
|
||||
aP1.Transform (aLoc.Transformation());
|
||||
}
|
||||
|
||||
gp_Vec aNormal;
|
||||
if (hasNormals)
|
||||
{
|
||||
aNormal = aTriangulation->Normal (aNodeIter);
|
||||
}
|
||||
else
|
||||
{
|
||||
const gp_Pnt2d& aUVNode = aTriangulation->UVNode (aNodeIter);
|
||||
gp_Pnt aDummyPnt;
|
||||
gp_Vec aV1, aV2;
|
||||
aSurface.D1 (aUVNode.X(), aUVNode.Y(), aDummyPnt, aV1, aV2);
|
||||
aNormal = aV1.Crossed (aV2);
|
||||
}
|
||||
|
||||
const Standard_Real aNormalLen = aNormal.Magnitude();
|
||||
if (aNormalLen > 1.e-10)
|
||||
{
|
||||
aNormal.Multiply (theLength / aNormalLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
aNormal.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
|
||||
std::cout << "Null normal at node X = " << aP1.X() << ", Y = " << aP1.Y() << ", Z = " << aP1.Z() << "\n";
|
||||
}
|
||||
|
||||
const gp_Pnt aP2 = aP1.Translated (aNormal);
|
||||
theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : addMeshNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void DBRep_DrawableShape::addMeshNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > & theNormals,
|
||||
const TopoDS_Shape& theShape,
|
||||
const Standard_Real theLength)
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
for (TopExp_Explorer aFaceIt(theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current());
|
||||
NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek(aFace);
|
||||
if (aFaceNormals == NULL)
|
||||
{
|
||||
aFaceNormals = theNormals.Bound(aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
|
||||
}
|
||||
|
||||
addMeshNormals (*aFaceNormals, aFace, theLength);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : addSurfaceNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean DBRep_DrawableShape::addSurfaceNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
|
||||
const TopoDS_Face& theFace,
|
||||
const Standard_Real theLength,
|
||||
const Standard_Integer theNbAlongU,
|
||||
const Standard_Integer theNbAlongV)
|
||||
{
|
||||
{
|
||||
TopLoc_Location aLoc;
|
||||
const Handle(Geom_Surface)& aSurface = BRep_Tool::Surface (theFace, aLoc);
|
||||
if (aSurface.IsNull())
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
Standard_Real aUmin = 0.0, aVmin = 0.0, aUmax = 0.0, aVmax = 0.0;
|
||||
BRepTools::UVBounds (theFace, aUmin, aUmax, aVmin, aVmax);
|
||||
const Standard_Boolean isUseMidU = (theNbAlongU == 1);
|
||||
const Standard_Boolean isUseMidV = (theNbAlongV == 1);
|
||||
const Standard_Real aDU = (aUmax - aUmin) / (isUseMidU ? 2 : (theNbAlongU - 1));
|
||||
const Standard_Real aDV = (aVmax - aVmin) / (isUseMidV ? 2 : (theNbAlongV - 1));
|
||||
|
||||
BRepAdaptor_Surface aSurface (theFace);
|
||||
for (Standard_Integer aUIter = 0; aUIter < theNbAlongU; ++aUIter)
|
||||
{
|
||||
const Standard_Real aU = aUmin + (isUseMidU ? 1 : aUIter) * aDU;
|
||||
for (Standard_Integer aVIter = 0; aVIter < theNbAlongV; ++aVIter)
|
||||
{
|
||||
const Standard_Real aV = aVmin + (isUseMidV ? 1 : aVIter) * aDV;
|
||||
|
||||
gp_Pnt aP1;
|
||||
gp_Vec aV1, aV2;
|
||||
aSurface.D1 (aU, aV, aP1, aV1, aV2);
|
||||
|
||||
gp_Vec aVec = aV1.Crossed (aV2);
|
||||
Standard_Real aNormalLen = aVec.Magnitude();
|
||||
if (aNormalLen > 1.e-10)
|
||||
{
|
||||
aVec.Multiply (theLength / aNormalLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
aVec.SetCoord (aNormalLen / 2.0, 0.0, 0.0);
|
||||
std::cout << "Null normal at U = " << aU << ", V = " << aV << "\n";
|
||||
}
|
||||
|
||||
const gp_Pnt aP2 = aP1.Translated(aVec);
|
||||
theNormals.Append (std::pair<gp_Pnt, gp_Pnt> (aP1, aP2));
|
||||
}
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : addSurfaceNormals
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void DBRep_DrawableShape::addSurfaceNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >& theNormals,
|
||||
const TopoDS_Shape& theShape,
|
||||
const Standard_Real theLength,
|
||||
const Standard_Integer theNbAlongU,
|
||||
const Standard_Integer theNbAlongV)
|
||||
{
|
||||
for (TopExp_Explorer aFaceIt (theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
|
||||
NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >* aFaceNormals = theNormals.ChangeSeek (aFace);
|
||||
if (aFaceNormals == NULL)
|
||||
{
|
||||
aFaceNormals = theNormals.Bound (aFace, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >());
|
||||
}
|
||||
addSurfaceNormals (*aFaceNormals, aFace, theLength, theNbAlongU, theNbAlongV);
|
||||
}
|
||||
}
|
||||
|
@ -17,39 +17,27 @@
|
||||
#ifndef _DBRep_DrawableShape_HeaderFile
|
||||
#define _DBRep_DrawableShape_HeaderFile
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <DBRep_ListOfEdge.hxx>
|
||||
#include <DBRep_ListOfFace.hxx>
|
||||
#include <DBRep_ListOfHideData.hxx>
|
||||
#include <Standard_Real.hxx>
|
||||
#include <Standard_Integer.hxx>
|
||||
#include <Draw_Color.hxx>
|
||||
#include <Standard_Boolean.hxx>
|
||||
#include <Draw_Drawable3D.hxx>
|
||||
#include <Standard_OStream.hxx>
|
||||
#include <Draw_Interpretor.hxx>
|
||||
class Standard_DomainError;
|
||||
class TopoDS_Shape;
|
||||
class Draw_Color;
|
||||
#include <NCollection_DataMap.hxx>
|
||||
#include <NCollection_Vector.hxx>
|
||||
#include <Standard_OStream.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
class Draw_Display;
|
||||
class Poly_Triangulation;
|
||||
class gp_Trsf;
|
||||
class Draw_Drawable3D;
|
||||
|
||||
|
||||
class DBRep_DrawableShape;
|
||||
DEFINE_STANDARD_HANDLE(DBRep_DrawableShape, Draw_Drawable3D)
|
||||
|
||||
//! Drawable structure to display a shape. Contains a
|
||||
//! list of edges and a list of faces.
|
||||
class DBRep_DrawableShape : public Draw_Drawable3D
|
||||
{
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(DBRep_DrawableShape, Draw_Drawable3D)
|
||||
public:
|
||||
|
||||
|
||||
Standard_EXPORT DBRep_DrawableShape(const TopoDS_Shape& C, const Draw_Color& FreeCol, const Draw_Color& ConnCol, const Draw_Color& EdgeCol, const Draw_Color& IsosCol, const Standard_Real size, const Standard_Integer nbisos, const Standard_Integer discret);
|
||||
|
||||
@ -106,10 +94,50 @@ public:
|
||||
//! u,v are the parameters of the closest point.
|
||||
Standard_EXPORT static void LastPick (TopoDS_Shape& S, Standard_Real& u, Standard_Real& v);
|
||||
|
||||
public:
|
||||
|
||||
//! Auxiliary method computing nodal normals for presentation purposes.
|
||||
//! @param theNormals [out] vector of computed normals (pair of points [from, to])
|
||||
//! @param theFace [in] input face
|
||||
//! @param theLength [in] normal length
|
||||
//! @return FALSE if normals can not be computed
|
||||
Standard_EXPORT static Standard_Boolean addMeshNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
|
||||
const TopoDS_Face& theFace,
|
||||
const Standard_Real theLength);
|
||||
|
||||
//! Auxiliary method computing nodal normals for presentation purposes.
|
||||
//! @param theNormals [out] map of computed normals (grouped per Face)
|
||||
//! @param theShape [in] input shape which will be exploded into Faces
|
||||
//! @param theLength [in] normal length
|
||||
Standard_EXPORT static void addMeshNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > & theNormals,
|
||||
const TopoDS_Shape& theShape,
|
||||
const Standard_Real theLength);
|
||||
|
||||
DEFINE_STANDARD_RTTIEXT(DBRep_DrawableShape,Draw_Drawable3D)
|
||||
//! Auxiliary method computing surface normals distributed within the Face for presentation purposes.
|
||||
//! @param theNormals [out] vector of computed normals (pair of points [from, to])
|
||||
//! @param theFace [in] input face
|
||||
//! @param theLength [in] normal length
|
||||
//! @param theNbAlongU [in] number along U
|
||||
//! @param theNbAlongV [in] number along V
|
||||
//! @return FALSE if normals can not be computed
|
||||
Standard_EXPORT static Standard_Boolean addSurfaceNormals (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >& theNormals,
|
||||
const TopoDS_Face& theFace,
|
||||
const Standard_Real theLength,
|
||||
const Standard_Integer theNbAlongU,
|
||||
const Standard_Integer theNbAlongV);
|
||||
|
||||
//! Auxiliary method computing surface normals distributed within the Face for presentation purposes.
|
||||
//! @param theNormals [out] map of computed normals (grouped per Face)
|
||||
//! @param theShape [in] input shape which will be exploded into Faces
|
||||
//! @param theLength [in] normal length
|
||||
//! @param theNbAlongU [in] number along U
|
||||
//! @param theNbAlongV [in] number along V
|
||||
//! @return FALSE if normals can not be computed
|
||||
Standard_EXPORT static void addSurfaceNormals (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >& theNormals,
|
||||
const TopoDS_Shape& theShape,
|
||||
const Standard_Real theLength,
|
||||
const Standard_Integer theNbAlongU,
|
||||
const Standard_Integer theNbAlongV);
|
||||
|
||||
private:
|
||||
|
||||
@ -142,13 +170,8 @@ private:
|
||||
Standard_Boolean myHid;
|
||||
Standard_Real myAng;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
DEFINE_STANDARD_HANDLE(DBRep_DrawableShape, Draw_Drawable3D)
|
||||
|
||||
#endif // _DBRep_DrawableShape_HeaderFile
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <Draw.hxx>
|
||||
#include <Draw_Appli.hxx>
|
||||
#include <DBRep.hxx>
|
||||
#include <DBRep_DrawableShape.hxx>
|
||||
|
||||
#include <Font_BRepFont.hxx>
|
||||
#include <Font_BRepTextBuilder.hxx>
|
||||
@ -129,6 +130,8 @@
|
||||
#include <BRepExtrema_ExtPC.hxx>
|
||||
#include <BRepExtrema_ExtPF.hxx>
|
||||
|
||||
#include <Prs3d_Arrow.hxx>
|
||||
#include <Prs3d_ArrowAspect.hxx>
|
||||
#include <Prs3d_DatumAspect.hxx>
|
||||
#include <Prs3d_Drawer.hxx>
|
||||
#include <Prs3d_VertexDrawMode.hxx>
|
||||
@ -5934,6 +5937,217 @@ static int VPriority (Draw_Interpretor& theDI,
|
||||
return 0;
|
||||
}
|
||||
|
||||
//! Auxiliary class for command vnormals.
|
||||
class MyShapeWithNormals : public AIS_Shape
|
||||
{
|
||||
DEFINE_STANDARD_RTTI_INLINE(MyShapeWithNormals, AIS_Shape);
|
||||
public:
|
||||
|
||||
Standard_Real NormalLength;
|
||||
Standard_Integer NbAlongU;
|
||||
Standard_Integer NbAlongV;
|
||||
Standard_Boolean ToUseMesh;
|
||||
Standard_Boolean ToOrient;
|
||||
|
||||
public:
|
||||
|
||||
//! Main constructor.
|
||||
MyShapeWithNormals (const TopoDS_Shape& theShape)
|
||||
: AIS_Shape (theShape),
|
||||
NormalLength(10),
|
||||
NbAlongU (1),
|
||||
NbAlongV (1),
|
||||
ToUseMesh (Standard_False),
|
||||
ToOrient (Standard_False) {}
|
||||
|
||||
protected:
|
||||
|
||||
//! Comnpute presentation.
|
||||
virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
|
||||
const Handle(Prs3d_Presentation)& thePrs,
|
||||
const Standard_Integer theMode) Standard_OVERRIDE
|
||||
{
|
||||
AIS_Shape::Compute (thePrsMgr, thePrs, theMode);
|
||||
|
||||
NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > > aNormalMap;
|
||||
if (ToUseMesh)
|
||||
{
|
||||
DBRep_DrawableShape::addMeshNormals (aNormalMap, myshape, NormalLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBRep_DrawableShape::addSurfaceNormals (aNormalMap, myshape, NormalLength, NbAlongU, NbAlongV);
|
||||
}
|
||||
|
||||
Handle(Graphic3d_Group) aPrsGroup = Prs3d_Root::NewGroup (thePrs);
|
||||
aPrsGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
|
||||
|
||||
const Standard_Real aArrowAngle = myDrawer->ArrowAspect()->Angle();
|
||||
const Standard_Real aArrowLength = myDrawer->ArrowAspect()->Length();
|
||||
for (NCollection_DataMap<TopoDS_Face, NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> > >::Iterator aFaceIt (aNormalMap);
|
||||
aFaceIt.More(); aFaceIt.Next())
|
||||
{
|
||||
const Standard_Boolean toReverse = ToOrient && aFaceIt.Key().Orientation() == TopAbs_REVERSED;
|
||||
Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (2 * aFaceIt.Value().Size());
|
||||
for (NCollection_Vector<std::pair<gp_Pnt, gp_Pnt> >::Iterator aPntIt (aFaceIt.Value()); aPntIt.More(); aPntIt.Next())
|
||||
{
|
||||
std::pair<gp_Pnt, gp_Pnt> aPair = aPntIt.Value();
|
||||
if (toReverse)
|
||||
{
|
||||
const gp_Vec aDir = aPair.first.XYZ() - aPair.second.XYZ();
|
||||
aPair.second = aPair.first.XYZ() + aDir.XYZ();
|
||||
}
|
||||
|
||||
aSegments->AddVertex (aPair.first);
|
||||
aSegments->AddVertex (aPair.second);
|
||||
Prs3d_Arrow::Draw (aPrsGroup, aPair.second, gp_Vec(aPair.first, aPair.second), aArrowAngle, aArrowLength);
|
||||
}
|
||||
|
||||
aPrsGroup->AddPrimitiveArray (aSegments);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//=======================================================================
|
||||
//function : VNormals
|
||||
//purpose : Displays/Hides normals calculated on shape geometry or retrieved from triangulation
|
||||
//=======================================================================
|
||||
static int VNormals (Draw_Interpretor& theDI,
|
||||
Standard_Integer theArgNum,
|
||||
const char** theArgs)
|
||||
{
|
||||
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
|
||||
if (aContext.IsNull())
|
||||
{
|
||||
std::cout << "Error: no view available, call 'vinit' before!\n";
|
||||
return 1;
|
||||
}
|
||||
else if (theArgNum < 2)
|
||||
{
|
||||
std::cout << "Error: wrong number of arguments! See usage:\n";
|
||||
theDI.PrintHelp (theArgs[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Standard_Integer anArgIter = 1;
|
||||
Standard_CString aShapeName = theArgs[anArgIter++];
|
||||
TopoDS_Shape aShape = DBRep::Get (aShapeName);
|
||||
Standard_Boolean isOn = Standard_True;
|
||||
if (aShape.IsNull())
|
||||
{
|
||||
std::cout << "Error: shape with name '" << aShapeName << "' is not found\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
ViewerTest_DoubleMapOfInteractiveAndName& aMap = GetMapOfAIS();
|
||||
Handle(MyShapeWithNormals) aShapePrs;
|
||||
if (aMap.IsBound2 (aShapeName))
|
||||
{
|
||||
aShapePrs = Handle(MyShapeWithNormals)::DownCast (aMap.Find2 (aShapeName));
|
||||
}
|
||||
|
||||
Standard_Boolean isUseMesh = Standard_False;
|
||||
Standard_Real aLength = 10.0;
|
||||
Standard_Integer aNbAlongU = 1, aNbAlongV = 1;
|
||||
Standard_Boolean isOriented = Standard_False;
|
||||
for (; anArgIter < theArgNum; ++anArgIter)
|
||||
{
|
||||
TCollection_AsciiString aParam (theArgs[anArgIter]);
|
||||
aParam.LowerCase();
|
||||
if (anArgIter == 2
|
||||
&& ViewerTest::ParseOnOff (aParam.ToCString(), isOn))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (aParam == "-usemesh"
|
||||
|| aParam == "-mesh")
|
||||
{
|
||||
isUseMesh = Standard_True;
|
||||
}
|
||||
else if (aParam == "-length"
|
||||
|| aParam == "-len")
|
||||
{
|
||||
++anArgIter;
|
||||
aLength = anArgIter < theArgNum ? Draw::Atof (theArgs[anArgIter]) : 0.0;
|
||||
if (Abs (aLength) <= gp::Resolution())
|
||||
{
|
||||
std::cout << "Syntax error: length should not be zero\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-orient"
|
||||
|| aParam == "-oriented")
|
||||
{
|
||||
isOriented = Standard_True;
|
||||
if (anArgIter + 1 < theArgNum
|
||||
&& ViewerTest::ParseOnOff (theArgs[anArgIter + 1], isOriented))
|
||||
{
|
||||
++anArgIter;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalongu"
|
||||
|| aParam == "-nbu")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongU = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
if (aNbAlongU < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlongU should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalongv"
|
||||
|| aParam == "-nbv")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongV = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
if (aNbAlongV < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlongV should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (aParam == "-nbalong"
|
||||
|| aParam == "-nbuv")
|
||||
{
|
||||
++anArgIter;
|
||||
aNbAlongU = anArgIter < theArgNum ? Draw::Atoi (theArgs[anArgIter]) : 0;
|
||||
aNbAlongV = aNbAlongU;
|
||||
if (aNbAlongU < 1)
|
||||
{
|
||||
std::cout << "Syntax error: NbAlong should be >=1\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: unknwon argument '" << aParam << "'\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (isOn)
|
||||
{
|
||||
if (aShapePrs.IsNull())
|
||||
{
|
||||
aShapePrs = new MyShapeWithNormals (aShape);
|
||||
}
|
||||
aShapePrs->ToUseMesh = isUseMesh;
|
||||
aShapePrs->ToOrient = isOriented;
|
||||
aShapePrs->NormalLength = aLength;
|
||||
aShapePrs->NbAlongU = aNbAlongU;
|
||||
aShapePrs->NbAlongV = aNbAlongV;
|
||||
VDisplayAISObject (aShapeName, aShapePrs);
|
||||
}
|
||||
else if (!aShapePrs.IsNull())
|
||||
{
|
||||
VDisplayAISObject (aShapeName, new AIS_Shape (aShape));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ObjectsCommands
|
||||
//purpose :
|
||||
@ -6232,4 +6446,11 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
|
||||
"vpriority [-noupdate|-update] name [value]\n\t\t prints or sets the display priority for an object",
|
||||
__FILE__,
|
||||
VPriority, group);
|
||||
|
||||
theCommands.Add ("vnormals",
|
||||
"vnormals usage:\n"
|
||||
"vnormals Shape [{on|off}=on] [-length {10}] [-nbAlongU {1}] [-nbAlongV {1}] [-nbAlong {1}]"
|
||||
"\n\t\t: [-useMesh] [-oriented {0}1}=0]"
|
||||
"\n\t\t: Displays/Hides normals calculated on shape geometry or retrieved from triangulation",
|
||||
__FILE__, VNormals, group);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user