0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / DsgPrs / DsgPrs_ShapeDirPresentation.cxx
1
2 // File:        DsgPrs_ShapeDirPresentation.cxx
3 // Created:     Fri Oct  6 12:33:19 1995
4 // Author:      Jing Cheng MEI
5 //              <mei@junon>
6
7 #include <DsgPrs_ShapeDirPresentation.ixx>
8
9 #include <gp.hxx>
10 #include <gp_Dir.hxx>
11 #include <Bnd_Box.hxx>
12
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>
18
19 #include <TopoDS_Shape.hxx>
20 #include <TopoDS.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>
33
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>
39
40 #include <Quantity_Length.hxx>
41 #include <TColgp_Array1OfPnt2d.hxx>
42
43
44
45 //=======================================================================
46 //function : FindPointOnFace
47 //purpose  : internal use
48 //=======================================================================
49
50 static Standard_Boolean FindPointOnFace(const TopoDS_Face& face, gp_Pnt2d& pt2d)
51 {
52   // discredisation of the external contour and computing the center of gravity
53
54   TopExp_Explorer wireExp;
55   wireExp.Init(face, TopAbs_WIRE);
56   if (!wireExp.More()) {
57     return Standard_False;
58   }
59
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;
64
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;
71       first = last;
72       last = change;
73     }
74     if (c2d->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
75       npoints = 2;
76       c2d->D0(first, points(1));
77       c2d->D0(last, points(2));
78     }
79     else {
80       Standard_Real deltaT, t;
81       npoints = nptt;
82       deltaT = (last - first) / (nptt-1);
83       for (Standard_Integer i=1; i<=nptt; i++) {
84         if (i == 1) {
85           t = first;
86         }
87         else if (i == nptt) {
88           t = last;
89         }
90         else {
91           t = first + (i-1) * deltaT;
92         }
93         c2d->D0(t, points(i));
94       } 
95     }
96       
97     // compute the contribution to the center of gravity
98
99     Standard_Real h, c, d;
100     for (Standard_Integer i=1; i<=npoints-1; i++) {
101
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();
105       area += h*c;
106       xcent += 0.5*h*c*d;
107       ycent += 0.5*h*h*c;
108     }
109   }
110
111   if (Abs(area) < gp::Resolution()) {
112     pt2d.SetCoord(points(1).X(), points(1).Y());
113     return Standard_False;
114   }
115
116   pt2d.SetCoord(xcent / area, ycent / area);
117
118   // verify that (upar vpar) is a point on the face
119
120   BRepClass_FaceClassifier fClass(face, pt2d, gp::Resolution());
121 #ifdef DEB
122   TopAbs_State state =
123 #endif
124                        fClass.State();
125   if ((fClass.State() == TopAbs_OUT) || (fClass.State() == TopAbs_UNKNOWN)) {
126     // try to find a point on face
127     pt2d=points(1);
128   }
129   return Standard_True;
130 }
131
132
133 //=======================================================================
134 //function : ComputeDir
135 //purpose  : internal use
136 //=======================================================================
137
138 static Standard_Boolean ComputeDir(const TopoDS_Shape& shape, gp_Pnt& pt, gp_Dir& dir, const Standard_Integer mode)
139 {
140   TopLoc_Location loc;
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());
147     if (mode == 0) {
148       lProps.SetParameter(last);
149     }
150     else if (mode == 1) {
151       lProps.SetParameter(first);
152     }
153     if (!lProps.IsTangentDefined()) {
154       return Standard_False;
155     }
156     pt = lProps.Value();
157     lProps.Tangent(dir);
158   }
159   else if (shape.ShapeType() == TopAbs_FACE) {
160     gp_Pnt2d pt2d;
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);
166     }
167     else {
168       Standard_Boolean found = FindPointOnFace(TopoDS::Face(shape), pt2d);
169       if (!found) {
170         return Standard_False;
171       }
172     }
173     
174     GeomLProp_SLProps lProps(surface, pt2d.X(), pt2d.Y(), 1, gp::Resolution());
175     if (!lProps.IsNormalDefined()) {
176       return Standard_False;
177     }
178
179     pt = lProps.Value();
180     dir = lProps.Normal();
181   }
182   if ((shape.Orientation() == TopAbs_FORWARD) && (mode == 1) ||
183       (shape.Orientation() == TopAbs_REVERSED) && (mode == 0)) {
184     dir.Reverse();
185   }
186   return Standard_True;
187 }  
188
189
190 //=======================================================================
191 //function : Add
192 //purpose  : 
193 //=======================================================================
194
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)
199      
200 {
201   if ((mode != 0) && (mode != 1)) {
202     return;
203   }
204   
205   gp_Dir dir;
206   gp_Pnt pt;
207   Bnd_Box box;
208
209   if (shape.ShapeType() == TopAbs_EDGE) {
210     ComputeDir(shape, pt, dir, mode);
211     BRepBndLib::Add(shape, box);
212   }
213   else if (shape.ShapeType() == TopAbs_FACE) {
214     ComputeDir(shape, pt, dir, mode);
215     BRepBndLib::Add(shape, box);
216   }    
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();
223       nb++;
224       if (nb <=3) {
225         BRepBndLib::Add(edge, box);
226       }
227       aList.Append(edge);
228     }
229
230     if (mode == 0) {
231       const TopoDS_Edge& edge = TopoDS::Edge(aList.Last());
232       ComputeDir(edge, pt, dir, mode);
233     }
234     else {
235       const TopoDS_Edge& edge = TopoDS::Edge(aList.First());
236       ComputeDir(edge, pt, dir, mode);
237     }
238   }
239   else {
240     TopExp_Explorer faceExp;
241     
242     TopTools_ListOfShape aList;
243     Standard_Integer nb = 0;
244     for (faceExp.Init(shape, TopAbs_FACE); faceExp.More(); faceExp.Next()) {
245       nb++;
246       const TopoDS_Face& face = TopoDS::Face(faceExp.Current());
247       aList.Append(face);
248       BRepBndLib::Add(face, box);
249       if (nb > 3) break;
250     }
251     const TopoDS_Face& face = TopoDS::Face(aList.Last());
252     ComputeDir(face, pt, dir, mode);
253   }  
254
255   Standard_Real c[6];
256   box.Get(c[0],c[1],c[2],c[3],c[4],c[5]);
257   
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;
262
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());
267   
268   Prs3d_Root::CurrentGroup(prs)->SetPrimitivesAspect(drawer->LineAspect()->Aspect());
269   Prs3d_Root::CurrentGroup(prs)->Polyline(line);
270
271   Prs3d_Arrow::Draw(prs, pt2, dir, M_PI/180.*10., leng*0.3);
272 }
273
274