0031704: Visualization - add an interactive object AIS_LightSource representing a...
[occt.git] / src / AIS / AIS_LightSource.cxx
CommitLineData
2daa5d95 1// Created on: 2020-09-07
2// Created by: Maria KRYLOVA
3// Copyright (c) 2020 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <AIS_LightSource.hxx>
17
18#include <AIS_InteractiveContext.hxx>
19#include <Graphic3d_ArrayOfPoints.hxx>
20#include <Graphic3d_ArrayOfSegments.hxx>
21#include <Graphic3d_ArrayOfTriangles.hxx>
22#include <Graphic3d_CView.hxx>
23#include <Graphic3d_Group.hxx>
24#include <Prs3d_ArrowAspect.hxx>
25#include <Prs3d_PointAspect.hxx>
26#include <Prs3d_Text.hxx>
27#include <Prs3d_ToolCylinder.hxx>
28#include <Prs3d_ToolSphere.hxx>
29#include <Select3D_SensitivePoint.hxx>
30#include <V3d_View.hxx>
31
32IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource, AIS_InteractiveObject)
33IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSourceOwner, SelectMgr_EntityOwner)
34
35// =======================================================================
36// function : AIS_LightSourceOwner
37// purpose :
38// =======================================================================
39AIS_LightSourceOwner::AIS_LightSourceOwner (const Handle(AIS_LightSource)& theObject,
40 Standard_Integer thePriority)
41: SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)&)theObject, thePriority)
42{
43 //
44}
45
46// =======================================================================
47// function : HandleMouseClick
48// purpose :
49// =======================================================================
50Standard_Boolean AIS_LightSourceOwner::HandleMouseClick (const Graphic3d_Vec2i& ,
51 Aspect_VKeyMouse theKey,
52 Aspect_VKeyFlags theFlags,
53 bool )
54{
55 AIS_LightSource* aLightSource = dynamic_cast<AIS_LightSource*>(mySelectable);
56 if (aLightSource != NULL
57 && aLightSource->ToSwitchOnClick()
58 && theKey == Aspect_VKeyMouse_LeftButton
59 && theFlags == Aspect_VKeyFlags_NONE)
60 {
61 aLightSource->Light()->SetEnabled (!aLightSource->Light()->IsEnabled());
62 aLightSource->updateLightAspects();
63 return true;
64 }
65 return false;
66}
67
68// =======================================================================
69// function : Constructor
70// purpose :
71// =======================================================================
72AIS_LightSource::AIS_LightSource (const Handle(Graphic3d_CLight)& theLight)
73: myLightSource (theLight),
74 myCodirMarkerType (Aspect_TOM_X),
75 myOpposMarkerType (Aspect_TOM_O_POINT),
76 mySize (50),
77 myNbArrows (5),
78 myNbSplitsQuadric (theLight->Type() == Graphic3d_TOLS_AMBIENT ? 10 : 30),
79 myNbSplitsArrow (20),
80 myIsZoomable (theLight->Type() == Graphic3d_TOLS_POSITIONAL
81 || theLight->Type() == Graphic3d_TOLS_SPOT),
82 myToDisplayName (true),
83 myToDisplayRange (true),
84 myToSwitchOnClick (true)
85{
86 myMarkerTypes[0] = Aspect_TOM_O_X;
87 myMarkerTypes[1] = Aspect_TOM_O_POINT;
88
89 myInfiniteState = true;
90
91 const Quantity_Color aColor = theLight->Color();
92 myDrawer->SetPointAspect (new Prs3d_PointAspect (myMarkerTypes[1], aColor, 3.0f));
93 myDisabledMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_EMPTY, aColor, 3.0f);
94
95 Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_UserDefined);
96 aMat.SetColor (aColor);
97 myDrawer->SetArrowAspect (new Prs3d_ArrowAspect());
98 myDrawer->ArrowAspect()->SetColor (aColor);
99 myDrawer->ArrowAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
100 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial() = aMat;
101 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (Aspect_TOM_EMPTY);
102 myDrawer->ArrowAspect()->Aspect()->SetMarkerScale (2.0f);
103 myArrowLineAspectShadow = new Graphic3d_AspectLine3d (Quantity_NOC_BLACK, Aspect_TOL_SOLID,
104 theLight->Type() != Graphic3d_TOLS_AMBIENT ? 3.0f : 1.0f);
105
106 myDrawer->SetupOwnShadingAspect();
107 myDrawer->ShadingAspect()->SetColor (aColor);
108 myDrawer->ShadingAspect()->SetMaterial (aMat);
109 myDrawer->ShadingAspect()->SetTransparency (0.5f);
110 myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
111
112 myDrawer->SetTextAspect (new Prs3d_TextAspect());
113 myDrawer->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
114 myDrawer->TextAspect()->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
115 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_LEFT);
116 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOPFIRSTLINE);
117
118 updateLightTransformPersistence();
119
120 myDrawer->SetDisplayMode (0);
121 myDynHilightDrawer = new Prs3d_Drawer();
122 myDynHilightDrawer->Link (myDrawer);
123 myDynHilightDrawer->SetDisplayMode (1);
124 myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
125
126 if (!myTransformPersistence.IsNull()
127 && myTransformPersistence->IsTrihedronOr2d())
128 {
129 myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
130 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
131 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_CENTER);
132 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOP);
133 }
134}
135
136// =======================================================================
137// function : updateLightAspects
138// purpose :
139// =======================================================================
140void AIS_LightSource::updateLightAspects()
141{
142 const Quantity_Color aBaseColor = myLightSource->Color();
143 const Quantity_Color aDimColor (aBaseColor.Rgb() * 0.3f);
144 const Quantity_Color aColor = myLightSource->IsEnabled() ? aBaseColor : aDimColor;
145 myDrawer->PointAspect()->SetColor (aColor);
146 myDrawer->PointAspect()->Aspect()->SetMarkerType (MarkerType (myLightSource->IsEnabled()));
147 myDrawer->PointAspect()->Aspect()->SetMarkerImage(MarkerImage(myLightSource->IsEnabled()));
148
149 myDisabledMarkerAspect->SetColor (aColor);
150 myDisabledMarkerAspect->SetMarkerScale(myDrawer->PointAspect()->Aspect()->MarkerScale());
151 myDisabledMarkerAspect->SetMarkerType (myLightSource->IsEnabled() ? Aspect_TOM_EMPTY : MarkerType (false));
152 myDisabledMarkerAspect->SetMarkerImage(MarkerImage (false));
153
154 myDrawer->ShadingAspect()->SetColor (aColor);
155 myDrawer->ArrowAspect() ->SetColor (aColor);
156 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial().SetColor (aColor);
157
158 if (myLightSource->Type() == Graphic3d_TOLS_DIRECTIONAL)
159 {
160 const Standard_Real anAngleTol = 2.0 * M_PI / 180.0;
161 Aspect_TypeOfMarker aDirMark = Aspect_TOM_EMPTY;
162 if (myLightSource->IsEnabled()
163 && myLightSource->IsHeadlight()
164 && myLightSource->Direction().IsParallel (gp::DZ(), anAngleTol))
165 {
166 aDirMark = myLightSource->Direction().IsOpposite (-gp::DZ(), anAngleTol) ? myOpposMarkerType : myCodirMarkerType;
167 }
168 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (aDirMark);
169 }
170 SynchronizeAspects();
171}
172
173// =======================================================================
174// function : updateLightTransformPersistence
175// purpose :
176// =======================================================================
177void AIS_LightSource::updateLightTransformPersistence()
178{
179 Handle(Graphic3d_TransformPers) aTrsfPers = myTransformPersistence;
180 switch (myLightSource->Type())
181 {
182 case Graphic3d_TOLS_AMBIENT:
183 {
184 if (!myIsZoomable)
185 {
186 if (aTrsfPers.IsNull() || !aTrsfPers->IsTrihedronOr2d())
187 {
188 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
189 }
190 }
191 else
192 {
193 aTrsfPers.Nullify();
194 }
195 break;
196 }
197 case Graphic3d_TOLS_DIRECTIONAL:
198 {
199 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers;
200 if (myIsZoomable)
201 {
202 aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : Graphic3d_TMF_None;
203 }
204 if (aMode != Graphic3d_TMF_None)
205 {
206 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
207 {
208 if (aMode == Graphic3d_TMF_CameraPers)
209 {
210 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
211 }
212 else
213 {
214 aTrsfPers = new Graphic3d_TransformPers (aMode, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
215 }
216 }
217 }
218 else
219 {
220 aTrsfPers.Nullify();
221 }
222 break;
223 }
224 case Graphic3d_TOLS_POSITIONAL:
225 case Graphic3d_TOLS_SPOT:
226 {
227 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight()
228 ? Graphic3d_TMF_CameraPers
229 : (!myIsZoomable ? Graphic3d_TMF_ZoomPers : Graphic3d_TMF_None);
230 if (aMode != Graphic3d_TMF_None)
231 {
232 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
233 {
234 if (aMode == Graphic3d_TMF_CameraPers)
235 {
236 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
237 }
238 else
239 {
240 aTrsfPers = new Graphic3d_TransformPers (aMode, myLightSource->Position());
241 }
242 }
243 if (aMode == Graphic3d_TMF_ZoomPers)
244 {
245 aTrsfPers->SetAnchorPoint (myLightSource->Position());
246 }
247 }
248 else
249 {
250 aTrsfPers.Nullify();
251 }
252 break;
253 }
254 }
255
256 SetTransformPersistence (aTrsfPers);
257}
258
259// =======================================================================
260// function : updateLightLocalTransformation
261// purpose :
262// =======================================================================
263void AIS_LightSource::updateLightLocalTransformation()
264{
265 myLocalTransformation.Nullify();
266 switch (myLightSource->Type())
267 {
268 case Graphic3d_TOLS_AMBIENT:
269 {
270 if (myIsZoomable)
271 {
272 gp_Trsf aTrsf;
273 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
274 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
275 }
276 break;
277 }
278 case Graphic3d_TOLS_DIRECTIONAL:
279 {
280 const gp_Pnt aLightPos = (myIsZoomable && !myLightSource->IsHeadlight())
281 ? myLightSource->DisplayPosition()
282 : gp::Origin();
283 gp_Trsf aTrsf;
284 const gp_Ax2 anAx2 (aLightPos, -myLightSource->Direction());
285 aTrsf.SetTransformation (anAx2, gp_Ax3());
286 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
287 break;
288 }
289 case Graphic3d_TOLS_POSITIONAL:
290 {
291 if (myIsZoomable)
292 {
293 gp_Trsf aTrsf;
294 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
295 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
296 }
297 break;
298 }
299 case Graphic3d_TOLS_SPOT:
300 {
301 gp_Trsf aTrsf;
302 const gp_Ax2 anAx2 (myIsZoomable ? myLightSource->Position() : gp::Origin(), -myLightSource->Direction());
303 aTrsf.SetTransformation (anAx2, gp_Ax3());
304 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
305 break;
306 }
307 }
308 UpdateTransformation();
309}
310
311// =======================================================================
312// function : setLocalTransformation
313// purpose :
314// =======================================================================
315void AIS_LightSource::setLocalTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
316{
317 const gp_Trsf aTrsf = theTrsf->Transformation();
318 switch (myLightSource->Type())
319 {
320 case Graphic3d_TOLS_AMBIENT:
321 {
322 break;
323 }
324 case Graphic3d_TOLS_DIRECTIONAL:
325 {
326 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
327 myLightSource->SetDirection (aNewDir);
328 if (myIsZoomable)
329 {
330 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
331 myLightSource->SetDisplayPosition (aNewPos);
332 }
333 break;
334 }
335 case Graphic3d_TOLS_POSITIONAL:
336 {
337 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
338 myLightSource->SetPosition (aNewPos);
339 break;
340 }
341 case Graphic3d_TOLS_SPOT:
342 {
343 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
344 myLightSource->SetPosition (aNewPos);
345
346 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
347 myLightSource->SetDirection (aNewDir);
348 break;
349 }
350 }
351
352 base_type::setLocalTransformation (new TopLoc_Datum3D (aTrsf));
353
354 updateLightAspects();
355 updateLightTransformPersistence();
356}
357
358// =======================================================================
359// function : Compute
360// purpose :
361// =======================================================================
362void AIS_LightSource::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
363 const Handle(Prs3d_Presentation)& thePrs,
364 const Standard_Integer theMode)
365{
366 thePrs->SetInfiniteState (myInfiniteState);
367 if (theMode != 0
368 && theMode != 1)
369 {
370 return;
371 }
372
373 if (theMode == 0)
374 {
375 updateLightAspects();
376 updateLightTransformPersistence();
377 updateLightLocalTransformation();
378 }
379
380 switch (myLightSource->Type())
381 {
382 case Graphic3d_TOLS_AMBIENT: computeAmbient (thePrs, theMode); break;
383 case Graphic3d_TOLS_DIRECTIONAL: computeDirectional(thePrs, theMode); break;
384 case Graphic3d_TOLS_POSITIONAL: computePositional (thePrs, theMode); break;
385 case Graphic3d_TOLS_SPOT: computeSpot (thePrs, theMode); break;
386 }
387
388 if (myToDisplayName)
389 {
390 TCollection_AsciiString aPrefix = !myTransformPersistence.IsNull()
391 && myTransformPersistence->IsTrihedronOr2d()
392 ? "\n" : " ";
393 TCollection_AsciiString aName = aPrefix + myLightSource->Name();
394 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), aName, gp::Origin());
395 }
396}
397
398// =======================================================================
399// function : computeAmbient
400// purpose :
401// =======================================================================
402void AIS_LightSource::computeAmbient (const Handle(Prs3d_Presentation)& thePrs,
403 const Standard_Integer theMode)
404{
405 const gp_XYZ aLightPos = gp::Origin().XYZ();
406 if (theMode == 0)
407 {
408 Handle(Graphic3d_ArrayOfTriangles) aSphereArray = Prs3d_ToolSphere::Create (mySize * 0.25, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
409 Handle(Graphic3d_Group) aSphereGroup = thePrs->NewGroup();
410 aSphereGroup->SetClosed (true);
411 aSphereGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
412 aSphereGroup->AddPrimitiveArray (aSphereArray);
413 }
414 if (theMode == 0
415 || theMode == 1)
416 {
417 const Standard_Real aLen = mySize * 0.25;
418 const Standard_Integer aNbArrows = 6;
419 const gp_Dir aDirList[6] = { -gp::DX(), gp::DX(), -gp::DY(), gp::DY(), -gp::DZ(), gp::DZ() };
420
421 const Prs3d_ToolCylinder aCylTool (mySize * 0.1, 0.0, mySize * 0.2, myNbSplitsArrow, myNbSplitsArrow);
422 Handle(Graphic3d_ArrayOfTriangles) aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
423 aNbArrows * aCylTool.TrianglesNb() * 3,
424 Graphic3d_ArrayFlags_VertexNormal);
425 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
426 for (Standard_Integer anArrIter = 0; anArrIter < aNbArrows; ++anArrIter)
427 {
428 const gp_Dir& aDir = aDirList[anArrIter];
429 const gp_XYZ aPnt = aLightPos + aDir.XYZ() * aLen;
430 if (!aLineArray.IsNull())
431 {
432 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 0.5);
433 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 1.5);
434 }
435 if (!aTrisArray.IsNull())
436 {
437 const gp_Ax3 aSystem (aPnt + aDir.XYZ() * aLen, -aDir);
438 gp_Trsf aTrsfCone;
439 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
440 aCylTool.FillArray (aTrisArray, aTrsfCone);
441 }
442 }
443
444 if (!aLineArray.IsNull())
445 {
446 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
447 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
448 aDirGroupShadow->AddPrimitiveArray (aLineArray);
449 }
450 if (!aTrisArray.IsNull())
451 {
452 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
453 anArrowGroup->SetClosed (true);
454 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
455 anArrowGroup->AddPrimitiveArray (aTrisArray);
456 }
457 }
458
459 {
460 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
461 aPoints->AddVertex (aLightPos);
462 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
463 aGroup->SetGroupPrimitivesAspect (theMode == 1 ? myDrawer->PointAspect()->Aspect() : myDisabledMarkerAspect);
464 aGroup->AddPrimitiveArray (aPoints);
465 }
466}
467
468// =======================================================================
469// function : computeDirectional
470// purpose :
471// =======================================================================
472void AIS_LightSource::computeDirectional (const Handle(Prs3d_Presentation)& thePrs,
473 const Standard_Integer theMode)
474{
475 const Standard_Real aDistance = mySize * 0.5;
476 const Standard_Real aStep = aDistance * 0.5;
477
478 // light source direction is set to local transformation
479 const gp_Dir aLightDir = -gp::DZ();
480 const gp_XYZ aLightPos = -aStep * aLightDir.XYZ();
481
482 Standard_Integer aNbArrows = 1;
483 if (myNbArrows >= 9) { aNbArrows = 9; }
484 else if (myNbArrows >= 5) { aNbArrows = 5; }
485 else if (myNbArrows >= 3) { aNbArrows = 3; }
486 TColgp_Array1OfPnt aPoints (1, aNbArrows);
487 {
488 const gp_Ax2 anAxes (gp::Origin(), aLightDir);
489 const gp_XYZ aDY = anAxes.YDirection().XYZ() * aStep;
490 const gp_XYZ aDX = anAxes.XDirection().XYZ() * aStep;
491 const gp_XYZ aDXY = aDX + aDY;
492 switch (aNbArrows)
493 {
494 case 9:
495 {
496 aPoints.SetValue (6, aLightPos + aDY);
497 aPoints.SetValue (7, aLightPos + aDX);
498 aPoints.SetValue (8, aLightPos - aDY);
499 aPoints.SetValue (9, aLightPos - aDX);
500 }
501 Standard_FALLTHROUGH
502 case 5:
503 {
504 aPoints.SetValue (4, aLightPos - aDY + aDX);
505 aPoints.SetValue (5, aLightPos + aDY - aDX);
506 }
507 Standard_FALLTHROUGH
508 case 3:
509 {
510 aPoints.SetValue (2, aLightPos + aDXY);
511 aPoints.SetValue (3, aLightPos - aDXY);
512 }
513 Standard_FALLTHROUGH
514 case 1:
515 {
516 aPoints.SetValue (1, aLightPos);
517 break;
518 }
519 }
520 }
521
522 const Prs3d_ToolCylinder aCylTool (aDistance * 0.1, 0.0, aDistance * 0.2, myNbSplitsArrow, myNbSplitsArrow);
523 Handle(Graphic3d_ArrayOfTriangles) aTrisArray;
524 if (theMode == 0)
525 {
526 aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
527 aNbArrows * aCylTool.TrianglesNb() * 3,
528 Graphic3d_ArrayFlags_VertexNormal);
529 }
530 Handle(Graphic3d_ArrayOfPoints) aPntArray = new Graphic3d_ArrayOfPoints (aNbArrows);
531 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
532 for (Standard_Integer aPntIter = aPoints.Lower(); aPntIter <= aPoints.Upper(); ++aPntIter)
533 {
534 const gp_Pnt aPnt = aPoints.Value (aPntIter);
535 if (!aPntArray.IsNull())
536 {
537 aPntArray->AddVertex (aPnt);
538 }
539 if (!aLineArray.IsNull())
540 {
541 aLineArray->AddVertex (aPnt);
542 aLineArray->AddVertex (gp_Pnt (aPnt.XYZ() + aLightDir.XYZ() * aDistance));
543 }
544 if (!aTrisArray.IsNull())
545 {
546 const gp_Ax3 aSystem (aPnt.XYZ() + aLightDir.XYZ() * aDistance, aLightDir);
547 gp_Trsf aTrsfCone;
548 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
549 aCylTool.FillArray (aTrisArray, aTrsfCone);
550 }
551 }
552
553 if (!aLineArray.IsNull() && theMode == 0)
554 {
555 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
556 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
557 aDirGroupShadow->AddPrimitiveArray (aLineArray);
558 }
559 if (!aLineArray.IsNull())
560 {
561 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
562 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
563 aDirGroup->AddPrimitiveArray (aLineArray);
564 }
565 if (!aTrisArray.IsNull())
566 {
567 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
568 anArrowGroup->SetClosed (true);
569 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
570 anArrowGroup->AddPrimitiveArray (aTrisArray);
571 }
572 if (!aPntArray.IsNull())
573 {
574 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
575 aGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
576 aGroup->AddPrimitiveArray (aPntArray);
577 }
578 {
579 Handle(Graphic3d_ArrayOfPoints) aPntArray2 = new Graphic3d_ArrayOfPoints (1);
580 aPntArray2->AddVertex (aLightPos);
581 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
582 aGroup->SetGroupPrimitivesAspect (myDisabledMarkerAspect);
583 aGroup->AddPrimitiveArray (aPntArray2);
584 }
585}
586
587// =======================================================================
588// function : computePositional
589// purpose :
590// =======================================================================
591void AIS_LightSource::computePositional (const Handle(Prs3d_Presentation)& thePrs,
592 const Standard_Integer theMode)
593{
594 // light source position is set to local transformation
595 const gp_XYZ aLightPos = gp::Origin().XYZ();
596 const Standard_Real aRadius = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : 0.0;
597 if (theMode == 0
598 && aRadius > 0.0
599 && myToDisplayRange)
600 {
601 Handle(Graphic3d_ArrayOfTriangles) aPosRangeArray = Prs3d_ToolSphere::Create (aRadius, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
602 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
603 aRangeGroup->SetClosed (true);
604 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
605 aRangeGroup->AddPrimitiveArray (aPosRangeArray);
606 }
607 {
608 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
609 aPoints->AddVertex (aLightPos);
610 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
611 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
612 aGroup->AddPrimitiveArray (aPoints);
613 }
614}
615
616// =======================================================================
617// function : computeSpot
618// purpose :
619// =======================================================================
620void AIS_LightSource::computeSpot (const Handle(Prs3d_Presentation)& thePrs,
621 const Standard_Integer theMode)
622{
623 // light source position and direction are set to local transformation
624 const gp_Dir aLightDir = -gp::DZ();
625 const gp_XYZ aLightPos = gp::Origin().XYZ();
626 const Standard_Real aDistance = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : mySize;
627 {
628 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
629 aPoints->AddVertex (aLightPos);
630
631 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
632 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
633 aGroup->AddPrimitiveArray (aPoints);
634 }
635
636 {
637 Handle(Graphic3d_ArrayOfSegments) aDirArray = new Graphic3d_ArrayOfSegments (2);
638 aDirArray->AddVertex (aLightPos);
639 aDirArray->AddVertex (gp_Pnt (aLightPos + aLightDir.XYZ() * aDistance));
640
641 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
642 aDirGroupShadow->SetClosed (true);
643 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
644 aDirGroupShadow->AddPrimitiveArray (aDirArray);
645
646 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
647 aDirGroup->SetClosed (true);
648 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
649 aDirGroup->AddPrimitiveArray (aDirArray);
650 }
651
652 if (theMode == 0
653 && myToDisplayRange)
654 {
655 const Standard_ShortReal aHalfAngle = myLightSource->Angle() / 2.0f;
656 const Standard_Real aRadius = aDistance * Tan (aHalfAngle);
657 gp_Ax3 aSystem (aLightPos + aLightDir.XYZ() * aDistance, -aLightDir);
658 gp_Trsf aTrsfCone;
659 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
660 Handle(Graphic3d_ArrayOfTriangles) aSpotRangeArray = Prs3d_ToolCylinder::Create (aRadius, 0.0, aDistance,
661 myNbSplitsQuadric, myNbSplitsQuadric, aTrsfCone);
662
663 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
664 aRangeGroup->SetClosed (true);
665 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
666 aRangeGroup->AddPrimitiveArray (aSpotRangeArray);
667 }
668}
669
670// =======================================================================
671// function : ComputeSelection
672// purpose :
673// =======================================================================
674void AIS_LightSource::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
675 const Standard_Integer theMode)
676{
677 if (theMode != 0)
678 {
679 return;
680 }
681
682 Handle(AIS_LightSourceOwner) anEntityOwner = new AIS_LightSourceOwner (this, 15);
683 {
684 Handle(Select3D_SensitivePoint) aSensPosition = new Select3D_SensitivePoint (anEntityOwner, gp::Origin());
685 aSensPosition->SetSensitivityFactor (12);
686 if (!myTransformPersistence.IsNull()
687 && myTransformPersistence->IsTrihedronOr2d())
688 {
689 aSensPosition->SetSensitivityFactor (Max (12, Standard_Integer (mySize * 0.5)));
690 }
691 theSel->Add (aSensPosition);
692 }
693}