Integration of OCCT 6.5.0 from SVN
[occt.git] / src / AIS / AIS_PerpendicularRelation.cxx
CommitLineData
7fd59977 1// File: AIS_PerpendicularRelation.cdl
2// Created: Tue Dec 5 15:09:04 1996
3// Author: Jean-Pierre COMBE/Odile Olivier
4// <ODL>
5
6#include <Standard_NotImplemented.hxx>
7
8#include <AIS_PerpendicularRelation.ixx>
9
10#include <AIS.hxx>
11
12#include <BRepBuilderAPI_MakeFace.hxx>
13#include <BRepAdaptor_Surface.hxx>
14#include <BRep_Tool.hxx>
15
16#include <DsgPrs_PerpenPresentation.hxx>
17
18#include <ElCLib.hxx>
19
20#include <Geom2d_Line.hxx>
21#include <GeomAPI.hxx>
22#include <Geom_Line.hxx>
23#include <Geom_Line.hxx>
24#include <Geom_Plane.hxx>
25
26#include <IntAna2d_AnaIntersection.hxx>
27#include <IntAna2d_IntPoint.hxx>
28
29#include <Precision.hxx>
30
31#include <Select3D_SensitiveSegment.hxx>
32#include <SelectMgr_EntityOwner.hxx>
33
34#include <TopoDS.hxx>
35#include <TopoDS_Edge.hxx>
36#include <TopoDS_Face.hxx>
37#include <TopoDS_Vertex.hxx>
38
39#include <gce_MakeDir.hxx>
40
41#include <gp_Pln.hxx>
42#include <gp_Pnt.hxx>
43#include <gp_Pnt2d.hxx>
44#include <gp_Trsf.hxx>
45#include <gp_Vec.hxx>
46#include <Geom_Ellipse.hxx>
47
48//=======================================================================
49//function : Constructor
50//purpose : TwoEdgesPerpendicular
51//=======================================================================
52AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape,
53 const TopoDS_Shape& aSShape,
54 const Handle(Geom_Plane)& aPlane)
55:AIS_Relation()
56{
57 myFShape = aFShape;
58 mySShape = aSShape;
59 myPlane = aPlane;
60}
61
62//=======================================================================
63//function : Constructor
64//purpose : TwoFacesPerpendicular
65//=======================================================================
66AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape,
67 const TopoDS_Shape& aSShape)
68:AIS_Relation()
69{
70 myFShape = aFShape;
71 mySShape = aSShape;
72}
73
74//=======================================================================
75//function : Compute
76//purpose :
77//=======================================================================
78void AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
79 const Handle(Prs3d_Presentation)& aPresentation,
80 const Standard_Integer)
81{
82 aPresentation->Clear();
83
84 if (myFShape.ShapeType() == mySShape.ShapeType()) {
85 switch (myFShape.ShapeType()) {
86 case TopAbs_FACE :
87 {
88 // cas perpendiculaire entre deux faces
89 ComputeTwoFacesPerpendicular(aPresentation);
90 }
91 break;
92 case TopAbs_EDGE :
93 {
94 // cas perpendiculaire entre deux edges
95 ComputeTwoEdgesPerpendicular(aPresentation);
96 }
97 break;
98 default:
99 break;
100 }
101 }
102 // Cas pas traite - Edge/Face
103}
104
105//=======================================================================
106//function : Compute
107//purpose : to avoid warning
108//=======================================================================
109void AIS_PerpendicularRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
110 const Handle(Prs3d_Presentation)& aPresentation)
111{
112// Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
113 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
114}
115
116//=======================================================================
117//function : Compute
118//purpose : to avoid warning
119//=======================================================================
120void AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
121 const Handle(Graphic2d_GraphicObject)&
122aGraphicObject,
123 const Standard_Integer anInteger)
124{
125// Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
126 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
127}
128
129void AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
130{
131// Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
132 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
133}
134
135//=======================================================================
136//function : ComputeSelection
137//purpose :
138//=======================================================================
139void AIS_PerpendicularRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
140 const Standard_Integer)
141{
142 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
143 const gp_Pnt& pos = myPosition;
144 Handle(Select3D_SensitiveSegment) seg;
145 Standard_Boolean ok1(Standard_False),ok2(Standard_False);
146
147 if (!myFAttach.IsEqual(pos,Precision::Confusion())) {
148 seg = new Select3D_SensitiveSegment(own,
149 myFAttach,
150 pos);
151 aSelection->Add(seg);
152 ok1 = Standard_True;
153 }
154 if (!mySAttach.IsEqual(myPosition,Precision::Confusion())) {
155 seg = new Select3D_SensitiveSegment(own,
156 mySAttach,
157 pos);
158 aSelection->Add(seg);
159 ok2 = Standard_True;
160 }
161
162 if (ok1 && ok2) {
163 gp_Vec vec1(gce_MakeDir(pos,myFAttach));
164 gp_Vec vec2(gce_MakeDir(pos,mySAttach));
165 Standard_Real dist1(pos.Distance(myFAttach));
166 Standard_Real dist2(pos.Distance(mySAttach));
167 vec1 *= dist1;
168 vec1 *= .2;
169 vec2 *= dist2;
170 vec2 *= .2;
171
172 gp_Pnt pAx11 = pos.Translated(vec1);
173 gp_Pnt pAx22 = pos.Translated(vec2);
174 gp_Pnt p_symb = pAx22.Translated(vec1);
175 seg = new Select3D_SensitiveSegment(own,pAx11,p_symb);
176 aSelection->Add(seg);
177 seg = new Select3D_SensitiveSegment(own,p_symb,pAx22);
178 aSelection->Add(seg);
179 }
180}
181
182//=======================================================================
183//function : ComputeTwoFacesPerpendicular
184//purpose :
185//=======================================================================
186void AIS_PerpendicularRelation::ComputeTwoFacesPerpendicular
187 (const Handle(Prs3d_Presentation)& /*aPresentation*/)
188{
189}
190
191//=======================================================================
192//function : ComputeTwoEdgesPerpendicular
193//purpose :
194//=======================================================================
195void AIS_PerpendicularRelation::ComputeTwoEdgesPerpendicular(const Handle(Prs3d_Presentation)& aPresentation)
196{
197 // 3d lines
198 Handle(Geom_Curve) geom1,geom2;
199 gp_Pnt pint3d,p1,p2,pAx1,pAx2,ptat11,ptat12,ptat21,ptat22;
200 Standard_Boolean isInfinite1,isInfinite2;
201 Handle(Geom_Curve) extCurv;
202 if ( !AIS::ComputeGeometry(TopoDS::Edge(myFShape),TopoDS::Edge(mySShape),
203 myExtShape,
204 geom1,geom2,
205 ptat11,ptat12,ptat21,ptat22,
206 extCurv,
207 isInfinite1,isInfinite2,
208 myPlane) ) return;
209
210 Standard_Boolean interOut1(Standard_False),interOut2(Standard_False);
211
212 Handle(Geom_Line) geom_lin1;
213 Handle(Geom_Line) geom_lin2;
214 if ( geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)) )
215 {
216 const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom1;
217 // construct lines through focuses
218 gp_Ax1 elAx = geom_el->XAxis();
219 gp_Lin ll (elAx);
220 geom_lin1 = new Geom_Line(ll);
221 Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
222 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
223 ptat11 = geom_el->Focus1().Translated(transvec);
224 ptat12 = geom_el->Focus2().Translated(-transvec);
225 interOut1 = Standard_True;
226 }
227 else if ( geom1->IsInstance(STANDARD_TYPE(Geom_Line)) )
228 {
229 geom_lin1 = (Handle(Geom_Line)&) geom1;
230 }
231 else return;
232
233 if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
234 {
235 const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom2;
236 // construct lines through focuses
237 gp_Ax1 elAx = geom_el->XAxis();
238 gp_Lin ll (elAx);
239 geom_lin2 = new Geom_Line(ll);
240 Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
241 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
242 ptat21 = geom_el->Focus1().Translated(transvec);
243 ptat22 = geom_el->Focus2().Translated(-transvec);
244 interOut2 = Standard_True;
245 }
246 else if ( geom2->IsInstance(STANDARD_TYPE(Geom_Line)) )
247 {
248 geom_lin2 = (Handle(Geom_Line)&) geom2;
249 }
250 else return;
251
252 // current face
253 BRepBuilderAPI_MakeFace makeface (myPlane->Pln());
254 TopoDS_Face face (makeface.Face());
255 BRepAdaptor_Surface adp (makeface.Face());
256
257 // 2d lines => projection of 3d on current plane
258 Handle(Geom2d_Curve) aGeom2dCurve = GeomAPI::To2d(geom_lin1,myPlane->Pln());
259 Handle(Geom2d_Line) lin1_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
260 aGeom2dCurve = GeomAPI::To2d(geom_lin2,myPlane->Pln());
261 Handle(Geom2d_Line) lin2_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
262 IntAna2d_AnaIntersection inter(lin1_2d->Lin2d(),lin2_2d->Lin2d());
263 if (!inter.IsDone()) return;
264 if (!inter.NbPoints()) return;
265
266 gp_Pnt2d pint(inter.Point(1).Value());
267 pint3d = adp.Value(pint.X(),pint.Y());
268
269 myPosition = pint3d;
270 // recherche points attache
271 Standard_Real par1,par2,curpar,pmin,pmax;//,dist,sign;
272 Standard_Real length(0.);
273
274 if ( isInfinite1 && isInfinite2 )
275 {
276 Standard_Real curpar1 = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
277 Standard_Real curpar2 = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
278 par1 = par2 = 50.;
279 p1 = p2 = pint3d;
280 myFAttach = ElCLib::Value(curpar1+par1,geom_lin1->Lin());
281 mySAttach = ElCLib::Value(curpar2+par2,geom_lin2->Lin());
282 }
283 else
284 {
285 Standard_Boolean lengthComputed (Standard_False);
286 if ( !isInfinite1 )
287 {
288 curpar = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
289 par1 = ElCLib::Parameter(geom_lin1->Lin(),ptat11);
290 par2 = ElCLib::Parameter(geom_lin1->Lin(),ptat12);
291 pmin = Min(par1,par2);
292 pmax = Max(par1,par2);
293
294 if ( myPosition.SquareDistance(ptat11) > myPosition.SquareDistance(ptat12) )
295 p1 = ptat11;
296 else
297 p1 = ptat12;
298 if ( (curpar < pmin) || (curpar > pmax) )
299 {
300 interOut1 = Standard_True;
301 }
302 if ( !isInfinite2 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
303 else length = 2.*ptat11.Distance(ptat12)/5.;
304 lengthComputed = Standard_True;
305 gp_Vec vec1 (gce_MakeDir(myPosition,p1));
306 vec1.Multiply(length);
307 pAx1 = myPosition.Translated(vec1);
308 myFAttach = pAx1;
309 }
310 if ( !isInfinite2 )
311 {
312 curpar = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
313 par1 = ElCLib::Parameter(geom_lin2->Lin(),ptat21);
314 par2 = ElCLib::Parameter(geom_lin2->Lin(),ptat22);
315 pmin = Min(par1,par2);
316 pmax = Max(par1,par2);
317
318 if ( myPosition.SquareDistance(ptat21) > myPosition.SquareDistance(ptat22) ) p2 = ptat21;
319 else p2 = ptat22;
320 if ( (curpar < pmin) || (curpar > pmax) )
321 {
322 interOut2 = Standard_True;
323 }
324 gp_Vec vec2 (gce_MakeDir(myPosition,p2));
325 if ( !lengthComputed )
326 {
327 if ( !isInfinite1 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
328 else length = 2.*ptat21.Distance(ptat22)/5.;
329 }
330 vec2.Multiply(length);
331 pAx2 = myPosition.Translated(vec2);
332 mySAttach = pAx2;
333 }
334 if ( isInfinite1 )
335 {
336 p1 = myPosition;
337 gp_Vec vec1(geom_lin1->Lin().Direction());
338 vec1.Multiply(length);
339 myFAttach = myPosition.Translated(vec1);
340 }
341 if ( isInfinite2 )
342 {
343 p2 = myPosition;
344 gp_Vec vec2(geom_lin2->Lin().Direction());
345 vec2.Multiply(length);
346 mySAttach = myPosition.Translated(vec2);
347 }
348 }
349 DsgPrs_PerpenPresentation::Add(aPresentation,myDrawer,
350 myFAttach,mySAttach,
351 p1,p2,
352 myPosition,
353 interOut1,interOut2);
354
355 if ( (myExtShape != 0) && !extCurv.IsNull()) {
356 gp_Pnt pf,pl;
357 if ( myExtShape == 1 ) {
358 if (!isInfinite1) {
359 pf = ptat11;
360 pl = ptat12;
361 }
362 aPresentation->SetInfiniteState(isInfinite1);
363 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
364 }
365 else {
366 if (!isInfinite2) {
367 pf = ptat21;
368 pl = ptat22;
369 }
370 aPresentation->SetInfiniteState(isInfinite2);
371 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);
372 }
373 }
374}