0025773: Visualization - remove AIS_Drawer class and transfer its Link() logic to...
[occt.git] / src / AIS / AIS_ParallelRelation.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Jean-Pierre COMBE/Odile Olivier
3// Copyright (c) 1996-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
7fd59977 17#include <AIS_ParallelRelation.ixx>
18
19#include <Standard_NotImplemented.hxx>
20#include <Standard_DomainError.hxx>
21
22#include <Precision.hxx>
23
24#include <TCollection_AsciiString.hxx>
25#include <TCollection_ExtendedString.hxx>
26
27#include <DsgPrs_LengthPresentation.hxx>
28
29#include <Prs3d_Drawer.hxx>
30#include <Prs3d_ArrowAspect.hxx>
a6eb515f 31#include <Prs3d_DimensionAspect.hxx>
7fd59977 32
33#include <AIS.hxx>
7fd59977 34
35#include <SelectMgr_EntityOwner.hxx>
36#include <Select3D_SensitiveSegment.hxx>
37#include <Select3D_SensitiveBox.hxx>
38
39#include <TopoDS.hxx>
40#include <TopExp_Explorer.hxx>
41#include <BRep_Tool.hxx>
42#include <BRepAdaptor_Surface.hxx>
43#include <BRepAdaptor_Curve.hxx>
44
45#include <gp_Lin.hxx>
46#include <gp_Pnt.hxx>
47#include <ElCLib.hxx>
48#include <gp_Pln.hxx>
49#include <gp_Dir.hxx>
50#include <gp_Ax1.hxx>
51#include <gp_Ax2.hxx>
52
53#include <gce_MakeLin.hxx>
54
55#include <Geom_Plane.hxx>
56#include <Geom_Line.hxx>
57#include <Geom_Ellipse.hxx>
58
59//=======================================================================
60//function : Constructor
61//purpose :
62//=======================================================================
63AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape,
64 const TopoDS_Shape& aSShape,
65 const Handle(Geom_Plane)& aPlane)
66{
67 myFShape = aFShape;
68 mySShape = aSShape;
69 myPlane = aPlane;
70 myAutomaticPosition = Standard_True;
71 myArrowSize = 0.01;
72 mySymbolPrs = DsgPrs_AS_BOTHAR;
73}
74
75//=======================================================================
76//function : Constructor
77//purpose :
78//=======================================================================
79AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape,
80 const TopoDS_Shape& aSShape,
81 const Handle(Geom_Plane)& aPlane,
82 const gp_Pnt& aPosition,
83 const DsgPrs_ArrowSide aSymbolPrs,
84 const Standard_Real anArrowSize)
85{
86 myFShape = aFShape;
87 mySShape = aSShape;
88 myPlane = aPlane;
89 myAutomaticPosition = Standard_False;
7fd59977 90 SetArrowSize( anArrowSize );
7fd59977 91 myPosition = aPosition;
92 mySymbolPrs = aSymbolPrs;
93}
94
95//=======================================================================
96//function : Compute
97//purpose :
98//=======================================================================
99void AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
100 const Handle(Prs3d_Presentation)& aPresentation,
101 const Standard_Integer)
102{
103 aPresentation->Clear();
104
105 switch (myFShape.ShapeType())
106 {
107 case TopAbs_FACE :
108 {
109 // cas longueur entre deux faces
110 ComputeTwoFacesParallel(aPresentation);
111 }
112 break;
113 case TopAbs_EDGE :
114 {
115 // cas longueur entre deux edges
116 ComputeTwoEdgesParallel(aPresentation);
117 }
118 break;
119 default:
120 break;
121 }
122}
123
124//=======================================================================
125//function : Compute
126//purpose : to avoid warning
127//=======================================================================
128void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
129 const Handle(Prs3d_Presentation)& aPresentation)
130{
131// Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
132 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
133}
134
857ffd5e 135void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Geom_Transformation)& aTransformation, const Handle(Prs3d_Presentation)& aPresentation)
7fd59977 136{
857ffd5e 137// Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
7fd59977 138 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
139}
140
141//=======================================================================
142//function : ComputeSelection
143//purpose :
144//=======================================================================
145void AIS_ParallelRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
146 const Standard_Integer)
147{
148 gp_Lin L1 (myFAttach,myDirAttach);
149 gp_Lin L2 (mySAttach,myDirAttach);
150 gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
151 gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
152
153 gp_Lin L3;
154 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
155
156 if (!Proj1.IsEqual(Proj2,Precision::Confusion()))
157 {
158 L3 = gce_MakeLin(Proj1,Proj2);
159 }
160 else
161 {
162 L3 = gce_MakeLin(Proj1,myDirAttach);
163 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
164 Handle(Select3D_SensitiveBox) box =
165 new Select3D_SensitiveBox(own,
166 myPosition.X(),
167 myPosition.Y(),
168 myPosition.Z(),
169 myPosition.X()+size,
170 myPosition.Y()+size,
171 myPosition.Z()+size);
172 aSelection->Add(box);
173 }
174 Standard_Real parmin,parmax,parcur;
175 parmin = ElCLib::Parameter(L3,Proj1);
176 parmax = parmin;
177
178 parcur = ElCLib::Parameter(L3,Proj2);
179 parmin = Min(parmin,parcur);
180 parmax = Max(parmax,parcur);
181
182 parcur = ElCLib::Parameter(L3,myPosition);
183 parmin = Min(parmin,parcur);
184 parmax = Max(parmax,parcur);
185
186 gp_Pnt PointMin = ElCLib::Value(parmin,L3);
187 gp_Pnt PointMax = ElCLib::Value(parmax,L3);
188
189 Handle(Select3D_SensitiveSegment) seg;
190
191 if (!PointMin.IsEqual(PointMax,Precision::Confusion()))
192 {
193 seg = new Select3D_SensitiveSegment(own,
194 PointMin,
195 PointMax);
196 aSelection->Add(seg);
197 }
198 if (!myFAttach.IsEqual(Proj1,Precision::Confusion()))
199 {
200 seg = new Select3D_SensitiveSegment(own, myFAttach, Proj1);
201 aSelection->Add(seg);
202 }
203 if (!mySAttach.IsEqual(Proj2,Precision::Confusion()))
204 {
205 seg = new Select3D_SensitiveSegment(own, mySAttach, Proj2);
206 aSelection->Add(seg);
207 }
208}
209
210//=======================================================================
211//function : ComputeTwoFacesParallel
212//purpose :
213//=======================================================================
214void AIS_ParallelRelation::ComputeTwoFacesParallel(const Handle(Prs3d_Presentation)&)
215{
216 Standard_NotImplemented::Raise("AIS_ParallelRelation::ComputeTwoFacesParallel not implemented");
217}
218
219//=======================================================================
220//function : ComputeTwoEdgesParallel
221//purpose :
222//=======================================================================
223void AIS_ParallelRelation::ComputeTwoEdgesParallel(const Handle(Prs3d_Presentation)& aPresentation)
224{
225 TopoDS_Edge E1 = TopoDS::Edge(myFShape);
226 TopoDS_Edge E2 = TopoDS::Edge(mySShape);
227
228 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
229 Handle(Geom_Curve) geom1,geom2;
230 Standard_Boolean isInfinite1,isInfinite2;
231 Handle(Geom_Curve) extCurv;
232 if (!AIS::ComputeGeometry(E1,E2,myExtShape,
233 geom1,geom2,
234 ptat11,ptat12,ptat21,ptat22,
235 extCurv,
236 isInfinite1,isInfinite2,
237 myPlane))
238 {
239 return;
240 }
241
242 aPresentation->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape != 0));
243
244 gp_Lin l1;
245 gp_Lin l2;
246 Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
247
248 if (geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
249 {
250 const Handle(Geom_Ellipse)& geom_el1 = (Handle(Geom_Ellipse)&) geom1;
251 // construct lines through focuses
252 gp_Ax1 elAx = geom_el1->XAxis();
253 l1 = gp_Lin(elAx);
254 Standard_Real focex = geom_el1->MajorRadius() - geom_el1->Focal()/2.0;
255 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
256 ptat11 = geom_el1->Focus1().Translated(transvec);
257 ptat12 = geom_el1->Focus2().Translated(-transvec);
258 isEl1 = Standard_True;
259 }
260 else if (geom1->IsInstance(STANDARD_TYPE(Geom_Line)))
261 {
262 const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
263 l1 = geom_lin1->Lin();
264 }
265 else return;
266
267 if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
268 {
269 const Handle(Geom_Ellipse)& geom_el2 = (Handle(Geom_Ellipse)&) geom2;
270 // construct lines through focuses
271 gp_Ax1 elAx = geom_el2->XAxis();
272 l2 = gp_Lin(elAx);
273 Standard_Real focex = geom_el2->MajorRadius() - geom_el2->Focal()/2.0;
274 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
275 ptat21 = geom_el2->Focus1().Translated(transvec);
276 ptat22 = geom_el2->Focus2().Translated(-transvec);
277 isEl2 = Standard_True;
278 }
279 else if (geom2->IsInstance(STANDARD_TYPE(Geom_Line)))
280 {
281 const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
282 l2 = geom_lin2->Lin();
283 }
284 else return;
285
286 const Handle(Geom_Line)& geom_lin1 = new Geom_Line(l1);
287 const Handle(Geom_Line)& geom_lin2 = new Geom_Line(l2);
288
289 myDirAttach = l1.Direction();
290 // size
7fd59977 291 if( !myArrowSizeIsDefined ) {
7fd59977 292 Standard_Real arrSize1 (myArrowSize), arrSize2 (myArrowSize);
293 if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/50.;
294 if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/50.;
295 myArrowSize = Max(myArrowSize,Max(arrSize1,arrSize2));
296// myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
7fd59977 297 }
7fd59977 298
299 if ( myAutomaticPosition )
300 {
301 gp_Pnt curpos;
302 if ( !isInfinite1 )
303 {
304 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
305 curpos.SetXYZ((ptat11.XYZ() + p2.XYZ())/2.);
306 }
307 else if ( !isInfinite2 )
308 {
309 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
310 curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
311 }
312 else
313 {
314 curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
315 }
316 // offset pour eviter confusion Edge et Dimension
317 gp_Vec offset (myDirAttach);
318 offset = offset*myArrowSize*(-10.);
319 curpos.Translate(offset);
320 myPosition = curpos;
321 }
322
323 // recherche points attache
324 if (!isInfinite1)
325 {
326 if ( isEl1 )
327 {
328 if (myPosition.Distance(ptat11) < myPosition.Distance(ptat12)) myFAttach = ptat12;
329 else myFAttach = ptat11;
330 }
331 else
332 {
333 if (myPosition.Distance(ptat11) > myPosition.Distance(ptat12)) myFAttach = ptat12;
334 else myFAttach = ptat11;
335 }
336 }
337 else
338 {
339 myFAttach = ElCLib::Value(ElCLib::Parameter(l1,myPosition),l1);
340 }
341
342 if (!isInfinite2)
343 {
344 if ( isEl2 )
345 {
346 if (myPosition.Distance(ptat21) < myPosition.Distance(ptat22)) mySAttach = ptat22;
347 else mySAttach = ptat21;
348 }
349 else
350 {
351 if (myPosition.Distance(ptat21) > myPosition.Distance(ptat22)) mySAttach = ptat22;
352 else mySAttach = ptat21;
353 }
354 }
355 else
356 {
357 mySAttach = ElCLib::Value(ElCLib::Parameter(l2,myPosition),l2);
358 }
359 TCollection_ExtendedString aText (" //");
360
361 if (l1.Distance(l2) <= Precision::Confusion())
362 {
363 myArrowSize = 0.;
364 }
a6eb515f 365 Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
366 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
7fd59977 367 arr->SetLength(myArrowSize);
a6eb515f 368 arr = la->ArrowAspect();
7fd59977 369 arr->SetLength(myArrowSize);
370 if ( myExtShape == 1)
371 mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
372 else if ( myExtShape == 2)
373 mySymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
374
375 DsgPrs_LengthPresentation::Add(aPresentation,
376 myDrawer,
377 aText,
378 myFAttach,
379 mySAttach,
380 myDirAttach,
381 myPosition,
382 mySymbolPrs);
383 if ( (myExtShape != 0) && !extCurv.IsNull())
384 {
385 gp_Pnt pf, pl;
386 if ( myExtShape == 1 )
387 {
388 if (!isInfinite1)
389 {
390 pf = ptat11;
391 pl = ptat12;
392 }
393 ComputeProjEdgePresentation(aPresentation,E1,geom_lin1,pf,pl);
394 }
395 else
396 {
397 if (!isInfinite2)
398 {
399 pf = ptat21;
400 pl = ptat22;
401 }
402 ComputeProjEdgePresentation(aPresentation,E2,geom_lin2,pf,pl);
403 }
404 }
405}