0023959: Getting rid of generic classes in Visualization: generic classes were remove...
[occt.git] / src / DsgPrs / DsgPrs_ShapeDirPresentation.cxx
CommitLineData
b311480e 1// Created on: 1995-10-06
2// Created by: Jing Cheng MEI
3// Copyright (c) 1995-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21#include <DsgPrs_ShapeDirPresentation.ixx>
22
23#include <gp.hxx>
24#include <gp_Dir.hxx>
25#include <Bnd_Box.hxx>
26
27#include <Geom2d_Line.hxx>
28#include <Geom_Curve.hxx>
29#include <Geom_Surface.hxx>
30#include <GeomLProp_CLProps.hxx>
31#include <GeomLProp_SLProps.hxx>
32
33#include <TopoDS_Shape.hxx>
34#include <TopoDS.hxx>
35#include <TopoDS_Face.hxx>
36#include <TopLoc_Location.hxx>
37#include <TopAbs_ShapeEnum.hxx>
38#include <TopAbs_Orientation.hxx>
39#include <TopExp_Explorer.hxx>
40#include <TopTools_ListOfShape.hxx>
41#include <BRep_Tool.hxx>
42#include <BRepTools_WireExplorer.hxx>
7fd59977 43#include <BRepClass_FaceClassifier.hxx>
44#include <BRepClass_Edge.hxx>
45#include <BRepBndLib.hxx>
46
47#include <Graphic3d_Group.hxx>
b8ddfc2f 48#include <Graphic3d_ArrayOfSegments.hxx>
7fd59977 49#include <Prs3d_Arrow.hxx>
50#include <Prs3d_LineAspect.hxx>
51
52#include <Quantity_Length.hxx>
53#include <TColgp_Array1OfPnt2d.hxx>
54
55
7fd59977 56//=======================================================================
57//function : FindPointOnFace
58//purpose : internal use
59//=======================================================================
60
61static Standard_Boolean FindPointOnFace(const TopoDS_Face& face, gp_Pnt2d& pt2d)
62{
63 // discredisation of the external contour and computing the center of gravity
64
65 TopExp_Explorer wireExp;
66 wireExp.Init(face, TopAbs_WIRE);
67 if (!wireExp.More()) {
68 return Standard_False;
69 }
70
71 Standard_Integer npoints, nptt = 21;
72 TColgp_Array1OfPnt2d points(1, nptt);
73 Standard_Real area=0., xcent=0., ycent=0.;
74 TopExp_Explorer edgeExp;
75
76 for (edgeExp.Init(wireExp.Current(), TopAbs_EDGE); edgeExp.More(); edgeExp.Next()) {
77 // discretize the 2d curve
78 Standard_Real first, last;
79 Handle(Geom2d_Curve) c2d = BRep_Tool::CurveOnSurface(TopoDS::Edge(edgeExp.Current()), face, first, last);
80 if (TopoDS::Edge(edgeExp.Current()).Orientation() == TopAbs_REVERSED) {
81 Standard_Real change = first;
82 first = last;
83 last = change;
84 }
85 if (c2d->DynamicType() == STANDARD_TYPE(Geom2d_Line)) {
86 npoints = 2;
87 c2d->D0(first, points(1));
88 c2d->D0(last, points(2));
89 }
90 else {
91 Standard_Real deltaT, t;
92 npoints = nptt;
93 deltaT = (last - first) / (nptt-1);
94 for (Standard_Integer i=1; i<=nptt; i++) {
95 if (i == 1) {
96 t = first;
97 }
98 else if (i == nptt) {
99 t = last;
100 }
101 else {
102 t = first + (i-1) * deltaT;
103 }
104 c2d->D0(t, points(i));
105 }
106 }
107
108 // compute the contribution to the center of gravity
109
110 Standard_Real h, c, d;
111 for (Standard_Integer i=1; i<=npoints-1; i++) {
112
113 h = 0.5*(points(i).Y() + points(i+1).Y());
114 c = points(i+1).X() - points(i).X();
115 d = points(i+1).X() + points(i).X();
116 area += h*c;
117 xcent += 0.5*h*c*d;
118 ycent += 0.5*h*h*c;
119 }
120 }
121
122 if (Abs(area) < gp::Resolution()) {
123 pt2d.SetCoord(points(1).X(), points(1).Y());
124 return Standard_False;
125 }
126
127 pt2d.SetCoord(xcent / area, ycent / area);
128
129 // verify that (upar vpar) is a point on the face
130
131 BRepClass_FaceClassifier fClass(face, pt2d, gp::Resolution());
6e6cd5d9 132
7fd59977 133 if ((fClass.State() == TopAbs_OUT) || (fClass.State() == TopAbs_UNKNOWN)) {
134 // try to find a point on face
135 pt2d=points(1);
136 }
137 return Standard_True;
138}
139
140
141//=======================================================================
142//function : ComputeDir
143//purpose : internal use
144//=======================================================================
145
146static Standard_Boolean ComputeDir(const TopoDS_Shape& shape, gp_Pnt& pt, gp_Dir& dir, const Standard_Integer mode)
147{
148 TopLoc_Location loc;
149 if (shape.ShapeType() == TopAbs_EDGE) {
150 Standard_Real first, last;
151 Handle(Geom_Curve) curv0 = BRep_Tool::Curve(TopoDS::Edge(shape), loc, first, last);
152 Handle(Geom_Curve) curve = Handle(Geom_Curve)::DownCast(curv0->Copy());
153 curve->Transform(loc.Transformation());
154 GeomLProp_CLProps lProps(curve, 1, gp::Resolution());
b8ddfc2f 155 lProps.SetParameter((mode == 0)? last : first);
156 if (!lProps.IsTangentDefined())
7fd59977 157 return Standard_False;
7fd59977 158 pt = lProps.Value();
159 lProps.Tangent(dir);
160 }
161 else if (shape.ShapeType() == TopAbs_FACE) {
162 gp_Pnt2d pt2d;
163 Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(shape));
164 if (BRep_Tool::NaturalRestriction(TopoDS::Face(shape))) {
165 Standard_Real u1, u2, v1, v2;
166 surface->Bounds(u1, u2, v1, v2);
167 pt2d.SetCoord((u1+u2)*0.5, (v1+v2)*0.5);
168 }
169 else {
b8ddfc2f 170 if (!FindPointOnFace(TopoDS::Face(shape), pt2d))
171 return Standard_False;
7fd59977 172 }
173
174 GeomLProp_SLProps lProps(surface, pt2d.X(), pt2d.Y(), 1, gp::Resolution());
b8ddfc2f 175 if (!lProps.IsNormalDefined())
7fd59977 176 return Standard_False;
7fd59977 177
178 pt = lProps.Value();
179 dir = lProps.Normal();
180 }
181 if ((shape.Orientation() == TopAbs_FORWARD) && (mode == 1) ||
182 (shape.Orientation() == TopAbs_REVERSED) && (mode == 0)) {
183 dir.Reverse();
184 }
185 return Standard_True;
186}
187
188
189//=======================================================================
190//function : Add
191//purpose :
192//=======================================================================
193
194void DsgPrs_ShapeDirPresentation::Add(const Handle(Prs3d_Presentation)& prs,
195 const Handle(Prs3d_Drawer)& drawer,
196 const TopoDS_Shape& shape,
197 const Standard_Integer mode)
198
199{
b8ddfc2f 200 if ((mode != 0) && (mode != 1))
7fd59977 201 return;
7fd59977 202
203 gp_Dir dir;
204 gp_Pnt pt;
205 Bnd_Box box;
206
207 if (shape.ShapeType() == TopAbs_EDGE) {
208 ComputeDir(shape, pt, dir, mode);
209 BRepBndLib::Add(shape, box);
210 }
211 else if (shape.ShapeType() == TopAbs_FACE) {
212 ComputeDir(shape, pt, dir, mode);
213 BRepBndLib::Add(shape, box);
214 }
215 else if (shape.ShapeType() == TopAbs_WIRE) {
216 TopTools_ListOfShape aList;
217 Standard_Integer nb = 0;
218 BRepTools_WireExplorer anExp;
219 for (anExp.Init(TopoDS::Wire(shape)); anExp.More(); anExp.Next()) {
220 const TopoDS_Edge& edge = anExp.Current();
221 nb++;
b8ddfc2f 222 if (nb <=3)
223 BRepBndLib::Add(edge, box);
7fd59977 224 aList.Append(edge);
225 }
226
227 if (mode == 0) {
228 const TopoDS_Edge& edge = TopoDS::Edge(aList.Last());
229 ComputeDir(edge, pt, dir, mode);
230 }
231 else {
232 const TopoDS_Edge& edge = TopoDS::Edge(aList.First());
233 ComputeDir(edge, pt, dir, mode);
234 }
235 }
236 else {
237 TopExp_Explorer faceExp;
238
239 TopTools_ListOfShape aList;
240 Standard_Integer nb = 0;
241 for (faceExp.Init(shape, TopAbs_FACE); faceExp.More(); faceExp.Next()) {
242 nb++;
243 const TopoDS_Face& face = TopoDS::Face(faceExp.Current());
244 aList.Append(face);
245 BRepBndLib::Add(face, box);
246 if (nb > 3) break;
247 }
248 const TopoDS_Face& face = TopoDS::Face(aList.Last());
249 ComputeDir(face, pt, dir, mode);
250 }
251
252 Standard_Real c[6];
253 box.Get(c[0],c[1],c[2],c[3],c[4],c[5]);
254
255 gp_Pnt ptmin(c[0], c[1], c[2]), ptmax(c[3], c[4], c[5]);
256 Quantity_Length leng = ptmin.Distance(ptmax)/3.;
257 // mei 19/09/96 extrusion infinie -> taille fixe
258 if (leng >= 20000.) leng = 50;
259
b8ddfc2f 260 gp_Pnt pt2(pt.XYZ()+leng*dir.XYZ());
261
7fd59977 262 Prs3d_Root::CurrentGroup(prs)->SetPrimitivesAspect(drawer->LineAspect()->Aspect());
b8ddfc2f 263
264 Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
265 aPrims->AddVertex(pt);
266 aPrims->AddVertex(pt2);
267 Prs3d_Root::CurrentGroup(prs)->AddPrimitiveArray(aPrims);
7fd59977 268
c6541a0c 269 Prs3d_Arrow::Draw(prs, pt2, dir, M_PI/180.*10., leng*0.3);
7fd59977 270}