1 // Created on: 2020-09-07
2 // Created by: Maria KRYLOVA
3 // Copyright (c) 2020 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
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.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <AIS_LightSource.hxx>
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>
32 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource, AIS_InteractiveObject)
33 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSourceOwner, SelectMgr_EntityOwner)
35 // =======================================================================
36 // function : AIS_LightSourceOwner
38 // =======================================================================
39 AIS_LightSourceOwner::AIS_LightSourceOwner (const Handle(AIS_LightSource)& theObject,
40 Standard_Integer thePriority)
41 : SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)&)theObject, thePriority)
46 // =======================================================================
47 // function : HandleMouseClick
49 // =======================================================================
50 Standard_Boolean AIS_LightSourceOwner::HandleMouseClick (const Graphic3d_Vec2i& ,
51 Aspect_VKeyMouse theKey,
52 Aspect_VKeyFlags theFlags,
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)
61 aLightSource->Light()->SetEnabled (!aLightSource->Light()->IsEnabled());
62 aLightSource->updateLightAspects();
68 // =======================================================================
69 // function : Constructor
71 // =======================================================================
72 AIS_LightSource::AIS_LightSource (const Handle(Graphic3d_CLight)& theLight)
73 : myLightSource (theLight),
74 myCodirMarkerType (Aspect_TOM_X),
75 myOpposMarkerType (Aspect_TOM_O_POINT),
78 myNbSplitsQuadric (theLight->Type() == Graphic3d_TOLS_AMBIENT ? 10 : 30),
80 myIsZoomable (theLight->Type() == Graphic3d_TOLS_POSITIONAL
81 || theLight->Type() == Graphic3d_TOLS_SPOT),
82 myToDisplayName (true),
83 myToDisplayRange (true),
84 myToSwitchOnClick (true)
86 myMarkerTypes[0] = Aspect_TOM_O_X;
87 myMarkerTypes[1] = Aspect_TOM_O_POINT;
89 myInfiniteState = true;
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);
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);
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);
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);
118 updateLightTransformPersistence();
120 myDrawer->SetDisplayMode (0);
121 myDynHilightDrawer = new Prs3d_Drawer();
122 myDynHilightDrawer->Link (myDrawer);
123 myDynHilightDrawer->SetDisplayMode (1);
124 myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
126 if (!myTransformPersistence.IsNull()
127 && myTransformPersistence->IsTrihedronOr2d())
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);
136 // =======================================================================
137 // function : updateLightAspects
139 // =======================================================================
140 void AIS_LightSource::updateLightAspects()
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()));
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));
154 myDrawer->ShadingAspect()->SetColor (aColor);
155 myDrawer->ArrowAspect() ->SetColor (aColor);
156 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial().SetColor (aColor);
158 if (myLightSource->Type() == Graphic3d_TOLS_DIRECTIONAL)
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))
166 aDirMark = myLightSource->Direction().IsOpposite (-gp::DZ(), anAngleTol) ? myOpposMarkerType : myCodirMarkerType;
168 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (aDirMark);
170 SynchronizeAspects();
173 // =======================================================================
174 // function : updateLightTransformPersistence
176 // =======================================================================
177 void AIS_LightSource::updateLightTransformPersistence()
179 Handle(Graphic3d_TransformPers) aTrsfPers = myTransformPersistence;
180 switch (myLightSource->Type())
182 case Graphic3d_TOLS_AMBIENT:
186 if (aTrsfPers.IsNull() || !aTrsfPers->IsTrihedronOr2d())
188 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
197 case Graphic3d_TOLS_DIRECTIONAL:
199 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers;
202 aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : Graphic3d_TMF_None;
204 if (aMode != Graphic3d_TMF_None)
206 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
208 if (aMode == Graphic3d_TMF_CameraPers)
210 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
214 aTrsfPers = new Graphic3d_TransformPers (aMode, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
224 case Graphic3d_TOLS_POSITIONAL:
225 case Graphic3d_TOLS_SPOT:
227 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight()
228 ? Graphic3d_TMF_CameraPers
229 : (!myIsZoomable ? Graphic3d_TMF_ZoomPers : Graphic3d_TMF_None);
230 if (aMode != Graphic3d_TMF_None)
232 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
234 if (aMode == Graphic3d_TMF_CameraPers)
236 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
240 aTrsfPers = new Graphic3d_TransformPers (aMode, myLightSource->Position());
243 if (aMode == Graphic3d_TMF_ZoomPers)
245 aTrsfPers->SetAnchorPoint (myLightSource->Position());
256 SetTransformPersistence (aTrsfPers);
259 // =======================================================================
260 // function : updateLightLocalTransformation
262 // =======================================================================
263 void AIS_LightSource::updateLightLocalTransformation()
265 myLocalTransformation.Nullify();
266 switch (myLightSource->Type())
268 case Graphic3d_TOLS_AMBIENT:
273 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
274 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
278 case Graphic3d_TOLS_DIRECTIONAL:
280 const gp_Pnt aLightPos = (myIsZoomable && !myLightSource->IsHeadlight())
281 ? myLightSource->DisplayPosition()
284 const gp_Ax2 anAx2 (aLightPos, -myLightSource->Direction());
285 aTrsf.SetTransformation (anAx2, gp_Ax3());
286 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
289 case Graphic3d_TOLS_POSITIONAL:
294 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
295 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
299 case Graphic3d_TOLS_SPOT:
302 const gp_Ax2 anAx2 (myIsZoomable ? myLightSource->Position() : gp::Origin(), -myLightSource->Direction());
303 aTrsf.SetTransformation (anAx2, gp_Ax3());
304 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
308 UpdateTransformation();
311 // =======================================================================
312 // function : setLocalTransformation
314 // =======================================================================
315 void AIS_LightSource::setLocalTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
317 const gp_Trsf aTrsf = theTrsf->Transformation();
318 switch (myLightSource->Type())
320 case Graphic3d_TOLS_AMBIENT:
324 case Graphic3d_TOLS_DIRECTIONAL:
326 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
327 myLightSource->SetDirection (aNewDir);
330 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
331 myLightSource->SetDisplayPosition (aNewPos);
335 case Graphic3d_TOLS_POSITIONAL:
337 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
338 myLightSource->SetPosition (aNewPos);
341 case Graphic3d_TOLS_SPOT:
343 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
344 myLightSource->SetPosition (aNewPos);
346 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
347 myLightSource->SetDirection (aNewDir);
352 base_type::setLocalTransformation (new TopLoc_Datum3D (aTrsf));
354 updateLightAspects();
355 updateLightTransformPersistence();
358 // =======================================================================
359 // function : Compute
361 // =======================================================================
362 void AIS_LightSource::Compute (const Handle(PrsMgr_PresentationManager)& ,
363 const Handle(Prs3d_Presentation)& thePrs,
364 const Standard_Integer theMode)
366 thePrs->SetInfiniteState (myInfiniteState);
375 updateLightAspects();
376 updateLightTransformPersistence();
377 updateLightLocalTransformation();
380 switch (myLightSource->Type())
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;
390 TCollection_AsciiString aPrefix = !myTransformPersistence.IsNull()
391 && myTransformPersistence->IsTrihedronOr2d()
393 TCollection_AsciiString aName = aPrefix + myLightSource->Name();
394 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), aName, gp::Origin());
398 // =======================================================================
399 // function : computeAmbient
401 // =======================================================================
402 void AIS_LightSource::computeAmbient (const Handle(Prs3d_Presentation)& thePrs,
403 const Standard_Integer theMode)
405 const gp_XYZ aLightPos = gp::Origin().XYZ();
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);
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() };
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)
428 const gp_Dir& aDir = aDirList[anArrIter];
429 const gp_XYZ aPnt = aLightPos + aDir.XYZ() * aLen;
430 if (!aLineArray.IsNull())
432 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 0.5);
433 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 1.5);
435 if (!aTrisArray.IsNull())
437 const gp_Ax3 aSystem (aPnt + aDir.XYZ() * aLen, -aDir);
439 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
440 aCylTool.FillArray (aTrisArray, aTrsfCone);
444 if (!aLineArray.IsNull())
446 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
447 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
448 aDirGroupShadow->AddPrimitiveArray (aLineArray);
450 if (!aTrisArray.IsNull())
452 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
453 anArrowGroup->SetClosed (true);
454 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
455 anArrowGroup->AddPrimitiveArray (aTrisArray);
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);
468 // =======================================================================
469 // function : computeDirectional
471 // =======================================================================
472 void AIS_LightSource::computeDirectional (const Handle(Prs3d_Presentation)& thePrs,
473 const Standard_Integer theMode)
475 const Standard_Real aDistance = mySize * 0.5;
476 const Standard_Real aStep = aDistance * 0.5;
478 // light source direction is set to local transformation
479 const gp_Dir aLightDir = -gp::DZ();
480 const gp_XYZ aLightPos = -aStep * aLightDir.XYZ();
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);
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;
496 aPoints.SetValue (6, aLightPos + aDY);
497 aPoints.SetValue (7, aLightPos + aDX);
498 aPoints.SetValue (8, aLightPos - aDY);
499 aPoints.SetValue (9, aLightPos - aDX);
504 aPoints.SetValue (4, aLightPos - aDY + aDX);
505 aPoints.SetValue (5, aLightPos + aDY - aDX);
510 aPoints.SetValue (2, aLightPos + aDXY);
511 aPoints.SetValue (3, aLightPos - aDXY);
516 aPoints.SetValue (1, aLightPos);
522 const Prs3d_ToolCylinder aCylTool (aDistance * 0.1, 0.0, aDistance * 0.2, myNbSplitsArrow, myNbSplitsArrow);
523 Handle(Graphic3d_ArrayOfTriangles) aTrisArray;
526 aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
527 aNbArrows * aCylTool.TrianglesNb() * 3,
528 Graphic3d_ArrayFlags_VertexNormal);
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)
534 const gp_Pnt aPnt = aPoints.Value (aPntIter);
535 if (!aPntArray.IsNull())
537 aPntArray->AddVertex (aPnt);
539 if (!aLineArray.IsNull())
541 aLineArray->AddVertex (aPnt);
542 aLineArray->AddVertex (gp_Pnt (aPnt.XYZ() + aLightDir.XYZ() * aDistance));
544 if (!aTrisArray.IsNull())
546 const gp_Ax3 aSystem (aPnt.XYZ() + aLightDir.XYZ() * aDistance, aLightDir);
548 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
549 aCylTool.FillArray (aTrisArray, aTrsfCone);
553 if (!aLineArray.IsNull() && theMode == 0)
555 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
556 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
557 aDirGroupShadow->AddPrimitiveArray (aLineArray);
559 if (!aLineArray.IsNull())
561 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
562 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
563 aDirGroup->AddPrimitiveArray (aLineArray);
565 if (!aTrisArray.IsNull())
567 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
568 anArrowGroup->SetClosed (true);
569 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
570 anArrowGroup->AddPrimitiveArray (aTrisArray);
572 if (!aPntArray.IsNull())
574 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
575 aGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
576 aGroup->AddPrimitiveArray (aPntArray);
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);
587 // =======================================================================
588 // function : computePositional
590 // =======================================================================
591 void AIS_LightSource::computePositional (const Handle(Prs3d_Presentation)& thePrs,
592 const Standard_Integer theMode)
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;
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);
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);
616 // =======================================================================
617 // function : computeSpot
619 // =======================================================================
620 void AIS_LightSource::computeSpot (const Handle(Prs3d_Presentation)& thePrs,
621 const Standard_Integer theMode)
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;
628 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
629 aPoints->AddVertex (aLightPos);
631 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
632 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
633 aGroup->AddPrimitiveArray (aPoints);
637 Handle(Graphic3d_ArrayOfSegments) aDirArray = new Graphic3d_ArrayOfSegments (2);
638 aDirArray->AddVertex (aLightPos);
639 aDirArray->AddVertex (gp_Pnt (aLightPos + aLightDir.XYZ() * aDistance));
641 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
642 aDirGroupShadow->SetClosed (true);
643 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
644 aDirGroupShadow->AddPrimitiveArray (aDirArray);
646 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
647 aDirGroup->SetClosed (true);
648 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
649 aDirGroup->AddPrimitiveArray (aDirArray);
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);
659 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
660 Handle(Graphic3d_ArrayOfTriangles) aSpotRangeArray = Prs3d_ToolCylinder::Create (aRadius, 0.0, aDistance,
661 myNbSplitsQuadric, myNbSplitsQuadric, aTrsfCone);
663 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
664 aRangeGroup->SetClosed (true);
665 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
666 aRangeGroup->AddPrimitiveArray (aSpotRangeArray);
670 // =======================================================================
671 // function : ComputeSelection
673 // =======================================================================
674 void AIS_LightSource::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
675 const Standard_Integer theMode)
682 Handle(AIS_LightSourceOwner) anEntityOwner = new AIS_LightSourceOwner (this, 15);
684 Handle(Select3D_SensitivePoint) aSensPosition = new Select3D_SensitivePoint (anEntityOwner, gp::Origin());
685 aSensPosition->SetSensitivityFactor (12);
686 if (!myTransformPersistence.IsNull()
687 && myTransformPersistence->IsTrihedronOr2d())
689 aSensPosition->SetSensitivityFactor (Max (12, Standard_Integer (mySize * 0.5)));
691 theSel->Add (aSensPosition);