2 // File: DsgPrs_ShapeDirPresentation.cxx
3 // Created: Fri Oct 6 12:33:19 1995
4 // Author: Jing Cheng MEI
7 #include <DsgPrs_ShapeDirPresentation.ixx>
11 #include <Bnd_Box.hxx>
13 #include <Geom2d_Line.hxx>
14 #include <Geom_Curve.hxx>
15 #include <Geom_Surface.hxx>
16 #include <GeomLProp_CLProps.hxx>
17 #include <GeomLProp_SLProps.hxx>
19 #include <TopoDS_Shape.hxx>
21 #include <TopoDS_Face.hxx>
22 #include <TopLoc_Location.hxx>
23 #include <TopAbs_ShapeEnum.hxx>
24 #include <TopAbs_Orientation.hxx>
25 #include <TopExp_Explorer.hxx>
26 #include <TopTools_ListOfShape.hxx>
27 #include <BRep_Tool.hxx>
28 #include <BRepTools_WireExplorer.hxx>
29 //#include <BRepAdaptor_Curve2d.hxx>
30 #include <BRepClass_FaceClassifier.hxx>
31 #include <BRepClass_Edge.hxx>
32 #include <BRepBndLib.hxx>
34 #include <Graphic3d_Group.hxx>
35 #include <Graphic3d_Vertex.hxx>
36 #include <Graphic3d_Array1OfVertex.hxx>
37 #include <Prs3d_Arrow.hxx>
38 #include <Prs3d_LineAspect.hxx>
40 #include <Quantity_Length.hxx>
41 #include <TColgp_Array1OfPnt2d.hxx>
45 //=======================================================================
46 //function : FindPointOnFace
47 //purpose : internal use
48 //=======================================================================
50 static Standard_Boolean FindPointOnFace(const TopoDS_Face& face, gp_Pnt2d& pt2d)
52 // discredisation of the external contour and computing the center of gravity
54 TopExp_Explorer wireExp;
55 wireExp.Init(face, TopAbs_WIRE);
56 if (!wireExp.More()) {
57 return Standard_False;
60 Standard_Integer npoints, nptt = 21;
61 TColgp_Array1OfPnt2d points(1, nptt);
62 Standard_Real area=0., xcent=0., ycent=0.;
63 TopExp_Explorer edgeExp;
65 for (edgeExp.Init(wireExp.Current(), TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) {
66 // discretize the 2d curve
67 Standard_Real first, last;
68 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(edgeExp.Current()), face, first, last);
69 if (TopoDS::Edge(edgeExp.Current()).Orientation() == TopAbs_REVERSED) {
70 Standard_Real change = first;
74 if (c2d->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
76 c2d->D0(first, points(1));
77 c2d->D0(last, points(2));
80 Standard_Real deltaT, t;
82 deltaT = (last - first) / (nptt-1);
83 for (Standard_Integer i=1; i<=nptt; i++) {
91 t = first + (i-1) * deltaT;
93 c2d->D0(t, points(i));
97 // compute the contribution to the center of gravity
99 Standard_Real h, c, d;
100 for (Standard_Integer i=1; i<=npoints-1; i++) {
102 h = 0.5*(points(i).Y() + points(i+1).Y());
103 c = points(i+1).X() - points(i).X();
104 d = points(i+1).X() + points(i).X();
111 if (Abs(area) < gp::Resolution()) {
112 pt2d.SetCoord(points(1).X(), points(1).Y());
113 return Standard_False;
116 pt2d.SetCoord(xcent / area, ycent / area);
118 // verify that (upar vpar) is a point on the face
120 BRepClass_FaceClassifier fClass(face, pt2d, gp::Resolution());
125 if ((fClass.State() == TopAbs_OUT) || (fClass.State() == TopAbs_UNKNOWN)) {
126 // try to find a point on face
129 return Standard_True;
133 //=======================================================================
134 //function : ComputeDir
135 //purpose : internal use
136 //=======================================================================
138 static Standard_Boolean ComputeDir(const TopoDS_Shape& shape, gp_Pnt& pt, gp_Dir& dir, const Standard_Integer mode)
141 if (shape.ShapeType() == TopAbs_EDGE) {
142 Standard_Real first, last;
143 Handle(Geom_Curve) curv0 = BRep_Tool::Curve(TopoDS::Edge(shape), loc, first, last);
144 Handle(Geom_Curve) curve = Handle(Geom_Curve)::DownCast(curv0->Copy());
145 curve->Transform(loc.Transformation());
146 GeomLProp_CLProps lProps(curve, 1, gp::Resolution());
148 lProps.SetParameter(last);
150 else if (mode == 1) {
151 lProps.SetParameter(first);
153 if (!lProps.IsTangentDefined()) {
154 return Standard_False;
159 else if (shape.ShapeType() == TopAbs_FACE) {
161 Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(shape));
162 if (BRep_Tool::NaturalRestriction(TopoDS::Face(shape))) {
163 Standard_Real u1, u2, v1, v2;
164 surface->Bounds(u1, u2, v1, v2);
165 pt2d.SetCoord((u1+u2)*0.5, (v1+v2)*0.5);
168 Standard_Boolean found = FindPointOnFace(TopoDS::Face(shape), pt2d);
170 return Standard_False;
174 GeomLProp_SLProps lProps(surface, pt2d.X(), pt2d.Y(), 1, gp::Resolution());
175 if (!lProps.IsNormalDefined()) {
176 return Standard_False;
180 dir = lProps.Normal();
182 if ((shape.Orientation() == TopAbs_FORWARD) && (mode == 1) ||
183 (shape.Orientation() == TopAbs_REVERSED) && (mode == 0)) {
186 return Standard_True;
190 //=======================================================================
193 //=======================================================================
195 void DsgPrs_ShapeDirPresentation::Add(const Handle(Prs3d_Presentation)& prs,
196 const Handle(Prs3d_Drawer)& drawer,
197 const TopoDS_Shape& shape,
198 const Standard_Integer mode)
201 if ((mode != 0) && (mode != 1)) {
209 if (shape.ShapeType() == TopAbs_EDGE) {
210 ComputeDir(shape, pt, dir, mode);
211 BRepBndLib::Add(shape, box);
213 else if (shape.ShapeType() == TopAbs_FACE) {
214 ComputeDir(shape, pt, dir, mode);
215 BRepBndLib::Add(shape, box);
217 else if (shape.ShapeType() == TopAbs_WIRE) {
218 TopTools_ListOfShape aList;
219 Standard_Integer nb = 0;
220 BRepTools_WireExplorer anExp;
221 for (anExp.Init(TopoDS::Wire(shape)); anExp.More(); anExp.Next()) {
222 const TopoDS_Edge& edge = anExp.Current();
225 BRepBndLib::Add(edge, box);
231 const TopoDS_Edge& edge = TopoDS::Edge(aList.Last());
232 ComputeDir(edge, pt, dir, mode);
235 const TopoDS_Edge& edge = TopoDS::Edge(aList.First());
236 ComputeDir(edge, pt, dir, mode);
240 TopExp_Explorer faceExp;
242 TopTools_ListOfShape aList;
243 Standard_Integer nb = 0;
244 for (faceExp.Init(shape, TopAbs_FACE); faceExp.More(); faceExp.Next()) {
246 const TopoDS_Face& face = TopoDS::Face(faceExp.Current());
248 BRepBndLib::Add(face, box);
251 const TopoDS_Face& face = TopoDS::Face(aList.Last());
252 ComputeDir(face, pt, dir, mode);
256 box.Get(c[0],c[1],c[2],c[3],c[4],c[5]);
258 gp_Pnt ptmin(c[0], c[1], c[2]), ptmax(c[3], c[4], c[5]);
259 Quantity_Length leng = ptmin.Distance(ptmax)/3.;
260 // mei 19/09/96 extrusion infinie -> taille fixe
261 if (leng >= 20000.) leng = 50;
263 gp_Pnt pt2(pt.X()+leng*dir.X(), pt.Y()+leng*dir.Y(), pt.Z()+leng*dir.Z());
264 Graphic3d_Array1OfVertex line(1,2);
265 line(1).SetCoord(pt.X(), pt.Y(), pt.Z());
266 line(2).SetCoord(pt2.X(), pt2.Y(), pt2.Z());
268 Prs3d_Root::CurrentGroup(prs)->SetPrimitivesAspect(drawer->LineAspect()->Aspect());
269 Prs3d_Root::CurrentGroup(prs)->Polyline(line);
271 Prs3d_Arrow::Draw(prs, pt2, dir, M_PI/180.*10., leng*0.3);