Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
c5f20409cThis file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1991-07-04
// Created by: Christophe MARION
// Copyright (c) 1991-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <DBRep_DrawableShape.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRepTools.hxx>
#include <BRepTools_ShapeSet.hxx>
#include <DBRep.hxx>
#include <DBRep_Edge.hxx>
#include <DBRep_Face.hxx>
#include <DBRep_HideData.hxx>
#include <DBRep_IsoBuilder.hxx>
#include <DBRep_ListIteratorOfListOfEdge.hxx>
#include <DBRep_ListIteratorOfListOfFace.hxx>
#include <DBRep_ListIteratorOfListOfHideData.hxx>
#include <Draw_Appli.hxx>
#include <Draw_Color.hxx>
#include <Draw_Display.hxx>
#include <Draw_ProgressIndicator.hxx>
#include <Geom_BSplineCurve.hxx>
#include <gp_Trsf.hxx>
#include <Message_ProgressIndicator.hxx>
#include <HLRBRep.hxx>
#include <Poly_Connect.hxx>
#include <Poly_Polygon3D.hxx>
#include <Poly_PolygonOnTriangulation.hxx>
#include <Poly_Triangulation.hxx>
#include <Precision.hxx>
#include <Standard_Type.hxx>
#include <TColStd_DataMapOfIntegerInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
IMPLEMENT_STANDARD_RTTIEXT(DBRep_DrawableShape, Draw_Drawable3D)
static Standard_Real IsoRatio = 1.001;
static Standard_Integer MaxPlotCount = 5; // To avoid huge recursive calls in
static Standard_Integer PlotCount = 0; // PlotEdge and PlotIso for cases of "bad"
// curves and surfaces
// Set PlotCount = 0 before first call of
// PlotEdge or PlotIso
static TopoDS_Shape pickshape;
static Standard_Real upick, vpick;
#ifdef _WIN32
extern Draw_Viewer dout;
#endif
//=================================================================================================
DBRep_DrawableShape::DBRep_DrawableShape(const TopoDS_Shape& aShape,
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)
: mySize(size),
myDiscret(discret),
myFreeCol(FreeCol),
myConnCol(ConnCol),
myEdgeCol(EdgeCol),
myIsosCol(IsosCol),
myNbIsos(nbisos),
myDispOr(Standard_False),
mytriangulations(Standard_False),
mypolygons(Standard_False),
myHLR(Standard_False),
myRg1(Standard_False),
myRgN(Standard_False),
myHid(Standard_False)
{
myShape = aShape;
}
//=================================================================================================
void DBRep_DrawableShape::updateDisplayData() const
{
myFaces.Clear();
myEdges.Clear();
if (myShape.IsNull())
return;
//==============================================================
// Process the faces
//==============================================================
TopExp_Explorer ExpFace;
TopLoc_Location l;
for (ExpFace.Init(myShape, TopAbs_FACE); ExpFace.More(); ExpFace.Next())
{
TopoDS_Face TopologicalFace = TopoDS::Face(ExpFace.Current());
if (myNbIsos != 0)
{
const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopologicalFace, l);
if (!S.IsNull())
{
TopologicalFace.Orientation(TopAbs_FORWARD);
DBRep_IsoBuilder IsoBuild(TopologicalFace, mySize, myNbIsos);
myFaces.Append(new DBRep_Face(TopologicalFace, IsoBuild.NbDomains(), myIsosCol));
IsoBuild.LoadIsos(myFaces.Last());
}
else
myFaces.Append(new DBRep_Face(TopologicalFace, 0, myEdgeCol));
}
else
myFaces.Append(new DBRep_Face(TopologicalFace, 0, myEdgeCol));
}
//==============================================================
// process a 3D edge
//==============================================================
TopTools_IndexedDataMapOfShapeListOfShape edgemap;
TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, edgemap);
Standard_Integer iedge;
for (iedge = 1; iedge <= edgemap.Extent(); iedge++)
{
const TopoDS_Edge& theEdge = TopoDS::Edge(edgemap.FindKey(iedge));
// skip degenerated edges
if (BRep_Tool::Degenerated(theEdge))
continue;
// compute the number of faces
Standard_Integer nbf = edgemap(iedge).Extent();
Draw_Color EdgeColor;
switch (nbf)
{
case 0:
EdgeColor = myEdgeCol; // isolated edge
break;
case 1:
EdgeColor = myFreeCol; // edge in only one face
break;
default:
EdgeColor = myConnCol; // edge shared by at least two faces
}
myEdges.Append(new DBRep_Edge(theEdge, EdgeColor));
}
}
//=======================================================================
// function : ChangeNbIsos
// purpose : Changes the number of isoparametric curves in a shape.
//=======================================================================
void DBRep_DrawableShape::ChangeNbIsos(const Standard_Integer NbIsos)
{
myFaces.Clear();
myNbIsos = NbIsos;
TopExp_Explorer ExpFace;
TopLoc_Location l;
for (ExpFace.Init(myShape, TopAbs_FACE); ExpFace.More(); ExpFace.Next())
{
TopoDS_Face TopologicalFace = TopoDS::Face(ExpFace.Current());
const Handle(Geom_Surface)& S = BRep_Tool::Surface(TopologicalFace, l);
if (myNbIsos != 0)
{
if (!S.IsNull())
{
TopologicalFace.Orientation(TopAbs_FORWARD);
DBRep_IsoBuilder IsoBuild(TopologicalFace, mySize, myNbIsos);
myFaces.Append(new DBRep_Face(TopologicalFace, IsoBuild.NbDomains(), myIsosCol));
IsoBuild.LoadIsos(myFaces.Last());
}
else
myFaces.Append(new DBRep_Face(TopologicalFace, 0, myEdgeCol));
}
else
myFaces.Append(new DBRep_Face(TopologicalFace, 0, myEdgeCol));
}
}
//=======================================================================
// Function : NbIsos
// Purpose : Returns the number of isoparametric curves in a shape.
//=======================================================================
Standard_Integer DBRep_DrawableShape::NbIsos() const
{
return myNbIsos;
}
//=================================================================================================
Standard_Integer DBRep_DrawableShape::Discret() const
{
return myDiscret;
}
Standard_EXPORT Draw_Color DBRep_ColorOrientation(const TopAbs_Orientation Or);
static void PlotIso(Draw_Display& dis,
Handle(DBRep_Face)& F,
BRepAdaptor_Surface& S,
GeomAbs_IsoType T,
Standard_Real& U,
Standard_Real& V,
Standard_Real Step,
Standard_Boolean& halt)
{
++PlotCount;
gp_Pnt Pl, Pr, Pm;
if (T == GeomAbs_IsoU)
{
S.D0(U, V, Pl);
S.D0(U, V + Step / 2., Pm);
S.D0(U, V + Step, Pr);
}
else
{
S.D0(U, V, Pl);
S.D0(U + Step / 2., V, Pm);
S.D0(U + Step, V, Pr);
}
if (PlotCount > MaxPlotCount)
{
dis.DrawTo(Pr);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = (T == GeomAbs_IsoU) ? U : U + Step;
vpick = (T == GeomAbs_IsoU) ? V + Step : V;
halt = Standard_True;
};
return;
}
if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio * Pl.Distance(Pr))
{
dis.DrawTo(Pr);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = (T == GeomAbs_IsoU) ? U : U + Step;
vpick = (T == GeomAbs_IsoU) ? V + Step : V;
halt = Standard_True;
};
}
else if (T == GeomAbs_IsoU)
{
PlotIso(dis, F, S, T, U, V, Step / 2, halt);
Standard_Real aLocalV = V + Step / 2;
PlotIso(dis, F, S, T, U, aLocalV, Step / 2, halt);
}
else
{
PlotIso(dis, F, S, T, U, V, Step / 2, halt);
Standard_Real aLocalU = U + Step / 2;
PlotIso(dis, F, S, T, aLocalU, V, Step / 2, halt);
}
}
static void PlotEdge(Draw_Display& dis,
Handle(DBRep_Edge)& E,
const Adaptor3d_Curve& C,
Standard_Real& f,
Standard_Real step,
Standard_Boolean& halt)
{
++PlotCount;
gp_Pnt Pl, Pr, Pm;
C.D0(f, Pl);
C.D0(f + step / 2., Pm);
C.D0(f + step, Pr);
if (PlotCount > MaxPlotCount)
{
dis.DrawTo(Pr);
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = f + step;
vpick = 0;
halt = Standard_True;
}
return;
}
if (Pm.Distance(Pl) + Pm.Distance(Pr) <= IsoRatio * Pl.Distance(Pr))
{
dis.DrawTo(Pr);
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = f + step;
vpick = 0;
halt = Standard_True;
};
}
else
{
PlotEdge(dis, E, C, f, step / 2, halt);
Standard_Real aLocalF = f + step / 2;
PlotEdge(dis, E, C, aLocalF, step / 2, halt);
}
}
//=================================================================================================
void DBRep_DrawableShape::DrawOn(Draw_Display& dis) const
{
Standard_Boolean halt = Standard_False;
if (myShape.IsNull())
{
dis.SetColor(myConnCol);
dis.DrawString(gp_Pnt(0, 0, 0), "Null Shape");
return;
}
if (myFaces.IsEmpty() || myEdges.IsEmpty())
updateDisplayData();
// hidden lines
if (myHLR)
{
DBRep_DrawableShape* p = (DBRep_DrawableShape*)this;
p->DisplayHiddenLines(dis);
return;
}
GeomAbs_IsoType T;
Standard_Real Par, T1, T2;
Standard_Real U1, U2, V1, V2, stepU = 0., stepV = 0.;
// gp_Pnt P, P1;
gp_Pnt P;
Standard_Integer i, j;
// Faces
Handle(Poly_Triangulation) Tr;
TopLoc_Location aTempLoc;
TopLoc_Location loc;
DBRep_ListIteratorOfListOfFace itf(myFaces);
while (itf.More() && !halt)
{
const Handle(DBRep_Face)& F = itf.Value();
dis.SetColor(F->Color());
Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F->Face(), aTempLoc);
if (!aSurf.IsNull())
{
Standard_Boolean restriction = Standard_False;
if (aSurf->IsUPeriodic() || aSurf->IsVPeriodic())
{
Standard_Real SU1 = 0., SU2 = 0., SV1 = 0., SV2 = 0.;
Standard_Real FU1 = 0., FU2 = 0., FV1 = 0., FV2 = 0.;
aSurf->Bounds(SU1, SU2, SV1, SV2);
BRepTools::UVBounds(F->Face(), FU1, FU2, FV1, FV2);
if (aSurf->IsUPeriodic())
{
if (FU1 < SU1 || FU1 > SU2)
restriction = Standard_True;
if (!restriction && (FU2 < SU1 || FU2 > SU2))
restriction = Standard_True;
}
if (!restriction && aSurf->IsVPeriodic())
{
if (FV1 < SV1 || FV1 > SV2)
restriction = Standard_True;
if (!restriction && (FV2 < SV1 || FV2 > SV2))
restriction = Standard_True;
}
Standard_Boolean zeroS = (fabs(SU2 - SU1) <= 1.e-9 || fabs(SV2 - SV1) <= 1.e-9);
Standard_Boolean zeroF = (fabs(FU2 - FU1) <= 1.e-9 || fabs(FV2 - FV1) <= 1.e-9);
if (restriction && (zeroS || zeroF))
restriction = Standard_False;
if (restriction && (FU1 >= FU2 || FV1 >= FV2))
restriction = Standard_False;
if (restriction && (fabs(FU2 - FU1) > 4.1e+100 || fabs(FV2 - FV1) > 4.1e+100))
restriction = Standard_False;
}
BRepAdaptor_Surface S(F->Face(), restriction);
// BRepAdaptor_Surface S(F->Face(),Standard_False);
GeomAbs_SurfaceType SurfType = S.GetType();
// If the type of the surface is GeomAbs_SurfaceOfExtrusion or GeomAbs_SurfaceOfRevolution
#ifdef OCCT_DEBUG
GeomAbs_CurveType CurvType;
#else
GeomAbs_CurveType CurvType = GeomAbs_OtherCurve;
#endif
Standard_Integer N = F->NbIsos();
Standard_Integer Intrv, nbIntv;
Standard_Integer nbUIntv = S.NbUIntervals(GeomAbs_CN);
Standard_Integer nbVIntv = S.NbVIntervals(GeomAbs_CN);
TColStd_Array1OfReal TI(1, Max(nbUIntv, nbVIntv) + 1);
for (i = 1; i <= N; i++)
{
F->GetIso(i, T, Par, T1, T2);
if (T == GeomAbs_IsoU)
{
S.VIntervals(TI, GeomAbs_CN);
V1 = Max(T1, TI(1));
V2 = Min(T2, TI(2));
U1 = Par;
U2 = Par;
stepU = 0;
nbIntv = nbVIntv;
}
else
{
S.UIntervals(TI, GeomAbs_CN);
U1 = Max(T1, TI(1));
U2 = Min(T2, TI(2));
V1 = Par;
V2 = Par;
stepV = 0;
nbIntv = nbUIntv;
}
S.D0(U1, V1, P);
dis.MoveTo(P);
for (Intrv = 1; Intrv <= nbIntv; Intrv++)
{
if (TI(Intrv) <= T1 && TI(Intrv + 1) <= T1)
continue;
if (TI(Intrv) >= T2 && TI(Intrv + 1) >= T2)
continue;
if (T == GeomAbs_IsoU)
{
V1 = Max(T1, TI(Intrv));
V2 = Min(T2, TI(Intrv + 1));
stepV = (V2 - V1) / myDiscret;
}
else
{
U1 = Max(T1, TI(Intrv));
U2 = Min(T2, TI(Intrv + 1));
stepU = (U2 - U1) / myDiscret;
}
switch (SurfType)
{
//-------------GeomAbs_Plane---------------
case GeomAbs_Plane:
break;
//----GeomAbs_Cylinder GeomAbs_Cone------
case GeomAbs_Cylinder:
case GeomAbs_Cone:
if (T == GeomAbs_IsoV)
{
for (j = 1; j < myDiscret; j++)
{
U1 += stepU;
V1 += stepV;
S.D0(U1, V1, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = U1;
vpick = V1;
halt = Standard_True;
}
}
}
break;
//---GeomAbs_Sphere GeomAbs_Torus--------
// GeomAbs_BezierSurface GeomAbs_BezierSurface
case GeomAbs_Sphere:
case GeomAbs_Torus:
case GeomAbs_OffsetSurface:
case GeomAbs_OtherSurface:
for (j = 1; j < myDiscret; j++)
{
U1 += stepU;
V1 += stepV;
S.D0(U1, V1, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = U1;
vpick = V1;
halt = Standard_True;
}
}
break;
//-------------GeomAbs_BSplineSurface------
case GeomAbs_BezierSurface:
case GeomAbs_BSplineSurface:
for (j = 1; j <= myDiscret / 2; j++)
{
Handle(DBRep_Face) aLocalFace = F;
PlotCount = 0;
PlotIso(dis,
aLocalFace,
S,
T,
U1,
V1,
(T == GeomAbs_IsoV) ? stepU * 2. : stepV * 2.,
halt);
U1 += stepU * 2.;
V1 += stepV * 2.;
}
break;
//-------------GeomAbs_SurfaceOfExtrusion--
//-------------GeomAbs_SurfaceOfRevolution-
case GeomAbs_SurfaceOfExtrusion:
case GeomAbs_SurfaceOfRevolution:
if ((T == GeomAbs_IsoV && SurfType == GeomAbs_SurfaceOfRevolution)
|| (T == GeomAbs_IsoU && SurfType == GeomAbs_SurfaceOfExtrusion))
{
if (SurfType == GeomAbs_SurfaceOfExtrusion)
break;
for (j = 1; j < myDiscret; j++)
{
U1 += stepU;
V1 += stepV;
S.D0(U1, V1, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = U1;
vpick = V1;
halt = Standard_True;
}
}
}
else
{
CurvType = (S.BasisCurve())->GetType();
switch (CurvType)
{
case GeomAbs_Line:
break;
case GeomAbs_Circle:
case GeomAbs_Ellipse:
for (j = 1; j < myDiscret; j++)
{
U1 += stepU;
V1 += stepV;
S.D0(U1, V1, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = U1;
vpick = V1;
halt = Standard_True;
}
}
break;
case GeomAbs_Parabola:
case GeomAbs_Hyperbola:
case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve:
case GeomAbs_OffsetCurve:
case GeomAbs_OtherCurve:
for (j = 1; j <= myDiscret / 2; j++)
{
Handle(DBRep_Face) aLocalFace = F;
PlotCount = 0;
PlotIso(dis,
aLocalFace,
S,
T,
U1,
V1,
(T == GeomAbs_IsoV) ? stepU * 2. : stepV * 2.,
halt);
U1 += stepU * 2.;
V1 += stepV * 2.;
}
break;
}
}
}
}
S.D0(U2, V2, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = F->Face();
upick = U2;
vpick = V2;
halt = Standard_True;
}
}
}
//=====================================
// trace des eventuelles triangulations.
//=====================================
if (aSurf.IsNull() || mytriangulations)
{
Tr = BRep_Tool::Triangulation(F->Face(), loc);
if (!Tr.IsNull())
{
display(Tr, loc.Transformation(), dis);
}
}
itf.Next();
}
// Edges
DBRep_ListIteratorOfListOfEdge ite(myEdges);
while (ite.More() && !halt)
{
const Handle(DBRep_Edge)& E = ite.Value();
if (myDispOr)
dis.SetColor(DBRep_ColorOrientation(E->Edge().Orientation()));
else
dis.SetColor(E->Color());
// display geometrical curve if exists.
Standard_Boolean isgeom = BRep_Tool::IsGeometric(E->Edge());
Standard_Real aCheckU1, aCheckU2;
if (isgeom)
{
// check the range (to report bad edges)
BRep_Tool::Range(E->Edge(), aCheckU1, aCheckU2);
if (aCheckU2 < aCheckU1)
{
// bad orientation
std::cout << "DBRep_DrawableShape : Bad parameters on edge." << std::endl;
BRepTools::Dump(E->Edge(), std::cout);
ite.Next();
continue;
}
if (BRep_Tool::Degenerated(E->Edge()))
{
ite.Next();
continue;
}
BRepAdaptor_Curve C(E->Edge());
Standard_Real f = C.FirstParameter();
Standard_Real l = C.LastParameter();
if (Precision::IsNegativeInfinite(f))
{
if (Precision::IsPositiveInfinite(l))
{
f = -mySize;
l = mySize;
}
else
{
f = l - mySize;
}
}
else if (Precision::IsPositiveInfinite(l))
{
l = f + mySize;
}
Handle(Adaptor3d_Curve) HC = C.Trim(f, l, Precision::Confusion());
GeomAbs_CurveType CurvType = HC->GetType();
Standard_Integer intrv, nbintv = HC->NbIntervals(GeomAbs_CN);
TColStd_Array1OfReal TI(1, nbintv + 1);
HC->Intervals(TI, GeomAbs_CN);
HC->D0(HC->FirstParameter(), P);
dis.MoveTo(P);
for (intrv = 1; intrv <= nbintv; intrv++)
{
Standard_Real t = TI(intrv);
Standard_Real step = (TI(intrv + 1) - t) / myDiscret;
switch (CurvType)
{
case GeomAbs_Line:
break;
case GeomAbs_Circle:
case GeomAbs_Ellipse:
for (j = 1; j < myDiscret; j++)
{
t += step;
C.D0(t, P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = t;
vpick = 0;
halt = Standard_True;
}
}
break;
case GeomAbs_Parabola:
case GeomAbs_Hyperbola:
case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve:
case GeomAbs_OffsetCurve:
case GeomAbs_OtherCurve:
for (j = 1; j <= myDiscret / 2; j++)
{
Handle(DBRep_Edge) aLocaLEdge(E);
PlotCount = 0;
PlotEdge(dis, aLocaLEdge, *HC, t, step * 2., halt);
t += step * 2.;
}
break;
}
}
C.D0(HC->LastParameter(), P);
dis.DrawTo(P);
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = l;
vpick = 0;
halt = Standard_True;
}
if (myDispOr)
{
// display an arrow at the end
gp_Pnt aPnt;
gp_Vec V;
C.D1(l, aPnt, V);
gp_Pnt2d p1, p2;
dis.Project(aPnt, p1);
aPnt.Translate(V);
dis.Project(aPnt, p2);
gp_Vec2d v(p1, p2);
if (v.Magnitude() > gp::Resolution())
{
Standard_Real L = 20 / dis.Zoom();
Standard_Real H = 10 / dis.Zoom();
gp_Dir2d d(v);
p2.SetCoord(p1.X() - L * d.X() - H * d.Y(), p1.Y() - L * d.Y() + H * d.X());
dis.MoveTo(p2);
p2.SetCoord(p1.X() - L * d.X() + H * d.Y(), p1.Y() - L * d.Y() - H * d.X());
dis.DrawTo(p1);
dis.DrawTo(p2);
}
// gp_Vec tang;
// C.D1(l,P,tang);
}
}
//======================================
// trace des representations polygonales:
//======================================
if (!isgeom || mypolygons)
{
// Polygones 3d:
Handle(Poly_Polygon3D) Polyg = BRep_Tool::Polygon3D(E->Edge(), loc);
if (!Polyg.IsNull())
{
const TColgp_Array1OfPnt& Points = Polyg->Nodes();
Standard_Integer po;
for (po = Points.Lower() + 1; po <= Points.Upper(); po++)
{
dis.Draw((Points.Value(po - 1)).Transformed(loc), (Points.Value(po)).Transformed(loc));
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = 0;
vpick = 0;
halt = Standard_True;
}
}
}
else
{
// Polygone sur triangulation:
Handle(Poly_Triangulation) PolyTr;
Handle(Poly_PolygonOnTriangulation) Poly;
BRep_Tool::PolygonOnTriangulation(E->Edge(), Poly, PolyTr, loc);
if (!Poly.IsNull())
{
const TColStd_Array1OfInteger& Indices = Poly->Nodes();
for (i = Indices.Lower() + 1; i <= Indices.Upper(); i++)
{
dis.Draw(PolyTr->Node(Indices(i - 1)).Transformed(loc),
PolyTr->Node(Indices(i)).Transformed(loc));
if (dis.HasPicked())
{
pickshape = E->Edge();
upick = 0;
vpick = 0;
halt = Standard_True;
}
}
}
}
}
ite.Next();
}
// Vertices
TopExp_Explorer exv;
dis.SetColor(myConnCol);
for (exv.Init(myShape, TopAbs_VERTEX, TopAbs_EDGE); exv.More() && !halt; exv.Next())
{
if (myDispOr)
dis.SetColor(DBRep_ColorOrientation(exv.Current().Orientation()));
dis.DrawMarker(BRep_Tool::Pnt(TopoDS::Vertex(exv.Current())), Draw_Losange);
if (dis.HasPicked())
{
pickshape = exv.Current();
upick = 0;
vpick = 0;
halt = Standard_True;
}
}
}
//=================================================================================================
void DBRep_DrawableShape::DisplayHiddenLines(Draw_Display& dis)
{
Standard_Integer id = dis.ViewId();
// get the projection
gp_Trsf T;
dout.GetTrsf(id, T);
Standard_Real focal = -1;
if (!strcmp(dout.GetType(id), "PERS"))
focal = dout.Focal(id);
Standard_Real Ang, Def;
HLRBRep::PolyHLRAngleAndDeflection(myAng, Ang, Def);
IMeshTools_Parameters aMeshParams;
aMeshParams.Relative = Standard_True;
aMeshParams.Deflection = Def;
aMeshParams.Angle = Ang;
BRepMesh_IncrementalMesh MESH(myShape, aMeshParams);
Standard_Boolean recompute = Standard_True;
// find if the view must be recomputed
DBRep_ListIteratorOfListOfHideData it(myHidData);
while (it.More())
{
if (it.Value().ViewId() == id)
{
// we have the view
// but did we rotate it
Standard_Real ang = it.Value().Angle();
recompute = !it.Value().IsSame(T, focal) || myAng != ang;
if (recompute)
myHidData.Remove(it);
else
{
it.ChangeValue().DrawOn(dis, myRg1, myRgN, myHid, myConnCol, myIsosCol);
if (dis.HasPicked())
{
pickshape = it.Value().LastPick();
upick = 0;
vpick = 0;
}
}
break;
}
it.Next();
}
// recompute the hidden lines and display them
if (recompute)
{
DBRep_HideData theData;
myHidData.Append(theData);
myHidData.Last().Set(id, T, focal, myShape, myAng);
myHidData.Last().DrawOn(dis, myRg1, myRgN, myHid, myConnCol, myIsosCol);
if (dis.HasPicked())
{
pickshape = myHidData.Last().LastPick();
upick = 0;
vpick = 0;
}
}
}
//=================================================================================================
TopoDS_Shape DBRep_DrawableShape::Shape() const
{
return myShape;
}
//=================================================================================================
Handle(Draw_Drawable3D) DBRep_DrawableShape::Copy() const
{
Handle(DBRep_DrawableShape) D = new DBRep_DrawableShape(myShape,
myFreeCol,
myConnCol,
myEdgeCol,
myIsosCol,
mySize,
myNbIsos,
myDiscret);
return D;
}
//=================================================================================================
void DBRep_DrawableShape::DisplayOrientation(const Standard_Boolean D)
{
myDispOr = D;
}
//=================================================================================================
void DBRep_DrawableShape::DisplayTriangulation(const Standard_Boolean D)
{
mytriangulations = D;
}
//=================================================================================================
void DBRep_DrawableShape::DisplayPolygons(const Standard_Boolean D)
{
mypolygons = D;
}
//=================================================================================================
void DBRep_DrawableShape::DisplayHLR(const Standard_Boolean withHLR,
const Standard_Boolean withRg1,
const Standard_Boolean withRgN,
const Standard_Boolean withHid,
const Standard_Real ang)
{
myHLR = withHLR;
myRg1 = withRg1;
myRgN = withRgN;
myHid = withHid;
myAng = ang;
}
//=================================================================================================
Standard_Boolean DBRep_DrawableShape::DisplayTriangulation() const
{
return mytriangulations;
}
//=================================================================================================
Standard_Boolean DBRep_DrawableShape::DisplayPolygons() const
{
return mypolygons;
}
//=================================================================================================
void DBRep_DrawableShape::GetDisplayHLR(Standard_Boolean& withHLR,
Standard_Boolean& withRg1,
Standard_Boolean& withRgN,
Standard_Boolean& withHid,
Standard_Real& ang) const
{
withHLR = myHLR;
withRg1 = myRg1;
withRgN = myRgN;
withHid = myHid;
ang = myAng;
}
//=================================================================================================
void DBRep_DrawableShape::Dump(Standard_OStream& S) const
{
BRepTools::Dump(myShape, S);
}
//=================================================================================================
void DBRep_DrawableShape::Save(Standard_OStream& theStream) const
{
BRep_Builder aBuilder;
BRepTools_ShapeSet aShapeSet(aBuilder);
aShapeSet.Add(myShape);
Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
aShapeSet.Write(theStream, Message_ProgressIndicator::Start(aProgress));
if (aProgress.IsNull() || !aProgress->UserBreak())
{
aShapeSet.Write(myShape, theStream);
}
}
//=================================================================================================
Handle(Draw_Drawable3D) DBRep_DrawableShape::Restore(Standard_IStream& theStream)
{
const DBRep_Params& aParams = DBRep::Parameters();
BRep_Builder aBuilder;
BRepTools_ShapeSet aShapeSet(aBuilder);
Handle(Draw_ProgressIndicator) aProgress = Draw::GetProgressBar();
aShapeSet.Read(theStream, Message_ProgressIndicator::Start(aProgress));
if (!aProgress.IsNull() && aProgress->UserBreak())
{
return Handle(Draw_Drawable3D)();
}
TopoDS_Shape aTopoShape;
aShapeSet.Read(aTopoShape, theStream);
Handle(DBRep_DrawableShape) aDrawShape = new DBRep_DrawableShape(aTopoShape,
Draw_vert,
Draw_jaune,
Draw_rouge,
Draw_bleu,
aParams.Size,
aParams.NbIsos,
aParams.Discretization);
aDrawShape->DisplayTriangulation(aParams.DispTriangles);
aDrawShape->DisplayPolygons(aParams.DisplayPolygons);
aDrawShape->DisplayHLR(aParams.WithHLR,
aParams.WithRg1,
aParams.WithRgN,
aParams.WithHid,
aParams.HLRAngle);
return aDrawShape;
}
//=================================================================================================
void DBRep_DrawableShape::Whatis(Draw_Interpretor& s) const
{
if (myShape.IsNull())
{
return;
}
s << "shape " << TopAbs::ShapeTypeToString(myShape.ShapeType()) << " "
<< TopAbs::ShapeOrientationToString(myShape.Orientation());
if (myShape.Free())
s << " Free";
if (myShape.Modified())
s << " Modified";
if (myShape.Orientable())
s << " Orientable";
if (myShape.Closed())
s << " Closed";
if (myShape.Infinite())
s << " Infinite";
if (myShape.Convex())
s << " Convex";
}
//=================================================================================================
void DBRep_DrawableShape::LastPick(TopoDS_Shape& s, Standard_Real& u, Standard_Real& v)
{
s = pickshape;
u = upick;
v = vpick;
}
//=================================================================================================
void DBRep_DrawableShape::display(const Handle(Poly_Triangulation)& T,
const gp_Trsf& tr,
Draw_Display& dis) const
{
// Build the connect tool
Poly_Connect pc(T);
Standard_Integer i, j, nFree, nbTriangles = T->NbTriangles();
Standard_Integer t[3];
// count the free edges
nFree = 0;
for (i = 1; i <= nbTriangles; i++)
{
pc.Triangles(i, t[0], t[1], t[2]);
for (j = 0; j < 3; j++)
if (t[j] == 0)
nFree++;
}
// allocate the arrays
TColStd_Array1OfInteger Free(1, Max(1, 2 * nFree));
NCollection_Vector<NCollection_Vec2<Standard_Integer>> anInternal;
Standard_Integer fr = 1;
Standard_Integer n[3];
for (i = 1; i <= nbTriangles; i++)
{
pc.Triangles(i, t[0], t[1], t[2]);
T->Triangle(i).Get(n[0], n[1], n[2]);
for (j = 0; j < 3; j++)
{
Standard_Integer k = (j + 1) % 3;
if (t[j] == 0)
{
Free(fr) = n[j];
Free(fr + 1) = n[k];
fr += 2;
}
// internal edge if this triangle has a lower index than the adjacent
else if (i < t[j])
{
anInternal.Append(NCollection_Vec2<Standard_Integer>(n[j], n[k]));
}
}
}
// Display the edges
// free edges
Standard_Integer nn;
dis.SetColor(Draw_rouge);
nn = Free.Length() / 2;
for (i = 1; i <= nn; i++)
{
dis.Draw(T->Node(Free[2 * i - 1]).Transformed(tr), T->Node(Free[2 * i]).Transformed(tr));
}
// internal edges
dis.SetColor(Draw_bleu);
for (NCollection_Vector<NCollection_Vec2<Standard_Integer>>::Iterator anInterIter(anInternal);
anInterIter.More();
anInterIter.Next())
{
const Standard_Integer n1 = anInterIter.Value()[0];
const Standard_Integer n2 = anInterIter.Value()[1];
dis.Draw(T->Node(n1).Transformed(tr), T->Node(n2).Transformed(tr));
}
}
//=================================================================================================
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;
}
BRepAdaptor_Surface aSurface(theFace);
for (Standard_Integer aNodeIter = 1; aNodeIter <= aTriangulation->NbNodes(); ++aNodeIter)
{
gp_Pnt aP1 = aTriangulation->Node(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;
}
//=================================================================================================
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);
}
}
//=================================================================================================
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;
}
//=================================================================================================
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);
}
}