// Created on: 2020-09-07 // Created by: Maria KRYLOVA // Copyright (c) 2020 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource, AIS_InteractiveObject) IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSourceOwner, SelectMgr_EntityOwner) // ======================================================================= // function : AIS_LightSourceOwner // purpose : // ======================================================================= AIS_LightSourceOwner::AIS_LightSourceOwner (const Handle(AIS_LightSource)& theObject, Standard_Integer thePriority) : SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)&)theObject, thePriority) { // } // ======================================================================= // function : HandleMouseClick // purpose : // ======================================================================= Standard_Boolean AIS_LightSourceOwner::HandleMouseClick (const Graphic3d_Vec2i& , Aspect_VKeyMouse theKey, Aspect_VKeyFlags theFlags, bool ) { AIS_LightSource* aLightSource = dynamic_cast(mySelectable); if (aLightSource != NULL && aLightSource->ToSwitchOnClick() && theKey == Aspect_VKeyMouse_LeftButton && theFlags == Aspect_VKeyFlags_NONE) { aLightSource->Light()->SetEnabled (!aLightSource->Light()->IsEnabled()); aLightSource->updateLightAspects(); return true; } return false; } // ======================================================================= // function : Constructor // purpose : // ======================================================================= AIS_LightSource::AIS_LightSource (const Handle(Graphic3d_CLight)& theLight) : myLightSource (theLight), myCodirMarkerType (Aspect_TOM_X), myOpposMarkerType (Aspect_TOM_O_POINT), mySize (50), myNbArrows (5), myNbSplitsQuadric (theLight->Type() == Graphic3d_TOLS_AMBIENT ? 10 : 30), myNbSplitsArrow (20), myIsZoomable (theLight->Type() == Graphic3d_TOLS_POSITIONAL || theLight->Type() == Graphic3d_TOLS_SPOT), myToDisplayName (true), myToDisplayRange (true), myToSwitchOnClick (true) { myMarkerTypes[0] = Aspect_TOM_O_X; myMarkerTypes[1] = Aspect_TOM_O_POINT; myInfiniteState = true; const Quantity_Color aColor = theLight->Color(); myDrawer->SetPointAspect (new Prs3d_PointAspect (myMarkerTypes[1], aColor, 3.0f)); myDisabledMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_EMPTY, aColor, 3.0f); Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_UserDefined); aMat.SetColor (aColor); myDrawer->SetArrowAspect (new Prs3d_ArrowAspect()); myDrawer->ArrowAspect()->SetColor (aColor); myDrawer->ArrowAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT); myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial() = aMat; myDrawer->ArrowAspect()->Aspect()->SetMarkerType (Aspect_TOM_EMPTY); myDrawer->ArrowAspect()->Aspect()->SetMarkerScale (2.0f); myArrowLineAspectShadow = new Graphic3d_AspectLine3d (Quantity_NOC_BLACK, Aspect_TOL_SOLID, theLight->Type() != Graphic3d_TOLS_AMBIENT ? 3.0f : 1.0f); myDrawer->SetupOwnShadingAspect(); myDrawer->ShadingAspect()->SetColor (aColor); myDrawer->ShadingAspect()->SetMaterial (aMat); myDrawer->ShadingAspect()->SetTransparency (0.5f); myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT); myDrawer->SetTextAspect (new Prs3d_TextAspect()); myDrawer->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_SHADOW); myDrawer->TextAspect()->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK); myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_LEFT); myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOPFIRSTLINE); updateLightTransformPersistence(); myDrawer->SetDisplayMode (0); myDynHilightDrawer = new Prs3d_Drawer(); myDynHilightDrawer->Link (myDrawer); myDynHilightDrawer->SetDisplayMode (1); myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1); if (!myTransformPersistence.IsNull() && myTransformPersistence->IsTrihedronOr2d()) { myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost); myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost); myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_CENTER); myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOP); } } // ======================================================================= // function : updateLightAspects // purpose : // ======================================================================= void AIS_LightSource::updateLightAspects() { const Quantity_Color aBaseColor = myLightSource->Color(); const Quantity_Color aDimColor (aBaseColor.Rgb() * 0.3f); const Quantity_Color aColor = myLightSource->IsEnabled() ? aBaseColor : aDimColor; myDrawer->PointAspect()->SetColor (aColor); myDrawer->PointAspect()->Aspect()->SetMarkerType (MarkerType (myLightSource->IsEnabled())); myDrawer->PointAspect()->Aspect()->SetMarkerImage(MarkerImage(myLightSource->IsEnabled())); myDisabledMarkerAspect->SetColor (aColor); myDisabledMarkerAspect->SetMarkerScale(myDrawer->PointAspect()->Aspect()->MarkerScale()); myDisabledMarkerAspect->SetMarkerType (myLightSource->IsEnabled() ? Aspect_TOM_EMPTY : MarkerType (false)); myDisabledMarkerAspect->SetMarkerImage(MarkerImage (false)); myDrawer->ShadingAspect()->SetColor (aColor); myDrawer->ArrowAspect() ->SetColor (aColor); myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial().SetColor (aColor); if (myLightSource->Type() == Graphic3d_TOLS_DIRECTIONAL) { const Standard_Real anAngleTol = 2.0 * M_PI / 180.0; Aspect_TypeOfMarker aDirMark = Aspect_TOM_EMPTY; if (myLightSource->IsEnabled() && myLightSource->IsHeadlight() && myLightSource->Direction().IsParallel (gp::DZ(), anAngleTol)) { aDirMark = myLightSource->Direction().IsOpposite (-gp::DZ(), anAngleTol) ? myOpposMarkerType : myCodirMarkerType; } myDrawer->ArrowAspect()->Aspect()->SetMarkerType (aDirMark); } SynchronizeAspects(); } // ======================================================================= // function : updateLightTransformPersistence // purpose : // ======================================================================= void AIS_LightSource::updateLightTransformPersistence() { Handle(Graphic3d_TransformPers) aTrsfPers = myTransformPersistence; switch (myLightSource->Type()) { case Graphic3d_TOLS_AMBIENT: { if (!myIsZoomable) { if (aTrsfPers.IsNull() || !aTrsfPers->IsTrihedronOr2d()) { aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50)); } } else { aTrsfPers.Nullify(); } break; } case Graphic3d_TOLS_DIRECTIONAL: { Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers; if (myIsZoomable) { aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : Graphic3d_TMF_None; } if (aMode != Graphic3d_TMF_None) { if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode) { if (aMode == Graphic3d_TMF_CameraPers) { aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers); } else { aTrsfPers = new Graphic3d_TransformPers (aMode, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50)); } } } else { aTrsfPers.Nullify(); } break; } case Graphic3d_TOLS_POSITIONAL: case Graphic3d_TOLS_SPOT: { Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : (!myIsZoomable ? Graphic3d_TMF_ZoomPers : Graphic3d_TMF_None); if (aMode != Graphic3d_TMF_None) { if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode) { if (aMode == Graphic3d_TMF_CameraPers) { aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers); } else { aTrsfPers = new Graphic3d_TransformPers (aMode, myLightSource->Position()); } } if (aMode == Graphic3d_TMF_ZoomPers) { aTrsfPers->SetAnchorPoint (myLightSource->Position()); } } else { aTrsfPers.Nullify(); } break; } } SetTransformPersistence (aTrsfPers); } // ======================================================================= // function : updateLightLocalTransformation // purpose : // ======================================================================= void AIS_LightSource::updateLightLocalTransformation() { myLocalTransformation.Nullify(); switch (myLightSource->Type()) { case Graphic3d_TOLS_AMBIENT: { if (myIsZoomable) { gp_Trsf aTrsf; aTrsf.SetTranslation (gp::Origin(), myLightSource->Position()); myLocalTransformation = new TopLoc_Datum3D (aTrsf); } break; } case Graphic3d_TOLS_DIRECTIONAL: { const gp_Pnt aLightPos = (myIsZoomable && !myLightSource->IsHeadlight()) ? myLightSource->DisplayPosition() : gp::Origin(); gp_Trsf aTrsf; const gp_Ax2 anAx2 (aLightPos, -myLightSource->Direction()); aTrsf.SetTransformation (anAx2, gp_Ax3()); myLocalTransformation = new TopLoc_Datum3D (aTrsf); break; } case Graphic3d_TOLS_POSITIONAL: { if (myIsZoomable) { gp_Trsf aTrsf; aTrsf.SetTranslation (gp::Origin(), myLightSource->Position()); myLocalTransformation = new TopLoc_Datum3D (aTrsf); } break; } case Graphic3d_TOLS_SPOT: { gp_Trsf aTrsf; const gp_Ax2 anAx2 (myIsZoomable ? myLightSource->Position() : gp::Origin(), -myLightSource->Direction()); aTrsf.SetTransformation (anAx2, gp_Ax3()); myLocalTransformation = new TopLoc_Datum3D (aTrsf); break; } } UpdateTransformation(); } // ======================================================================= // function : setLocalTransformation // purpose : // ======================================================================= void AIS_LightSource::setLocalTransformation (const Handle(TopLoc_Datum3D)& theTrsf) { const gp_Trsf aTrsf = theTrsf->Transformation(); switch (myLightSource->Type()) { case Graphic3d_TOLS_AMBIENT: { break; } case Graphic3d_TOLS_DIRECTIONAL: { gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf); myLightSource->SetDirection (aNewDir); if (myIsZoomable) { gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf); myLightSource->SetDisplayPosition (aNewPos); } break; } case Graphic3d_TOLS_POSITIONAL: { gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf); myLightSource->SetPosition (aNewPos); break; } case Graphic3d_TOLS_SPOT: { gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf); myLightSource->SetPosition (aNewPos); gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf); myLightSource->SetDirection (aNewDir); break; } } base_type::setLocalTransformation (new TopLoc_Datum3D (aTrsf)); updateLightAspects(); updateLightTransformPersistence(); } // ======================================================================= // function : Compute // purpose : // ======================================================================= void AIS_LightSource::Compute (const Handle(PrsMgr_PresentationManager3d)& , const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { thePrs->SetInfiniteState (myInfiniteState); if (theMode != 0 && theMode != 1) { return; } if (theMode == 0) { updateLightAspects(); updateLightTransformPersistence(); updateLightLocalTransformation(); } switch (myLightSource->Type()) { case Graphic3d_TOLS_AMBIENT: computeAmbient (thePrs, theMode); break; case Graphic3d_TOLS_DIRECTIONAL: computeDirectional(thePrs, theMode); break; case Graphic3d_TOLS_POSITIONAL: computePositional (thePrs, theMode); break; case Graphic3d_TOLS_SPOT: computeSpot (thePrs, theMode); break; } if (myToDisplayName) { TCollection_AsciiString aPrefix = !myTransformPersistence.IsNull() && myTransformPersistence->IsTrihedronOr2d() ? "\n" : " "; TCollection_AsciiString aName = aPrefix + myLightSource->Name(); Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), aName, gp::Origin()); } } // ======================================================================= // function : computeAmbient // purpose : // ======================================================================= void AIS_LightSource::computeAmbient (const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { const gp_XYZ aLightPos = gp::Origin().XYZ(); if (theMode == 0) { Handle(Graphic3d_ArrayOfTriangles) aSphereArray = Prs3d_ToolSphere::Create (mySize * 0.25, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf()); Handle(Graphic3d_Group) aSphereGroup = thePrs->NewGroup(); aSphereGroup->SetClosed (true); aSphereGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect()); aSphereGroup->AddPrimitiveArray (aSphereArray); } if (theMode == 0 || theMode == 1) { const Standard_Real aLen = mySize * 0.25; const Standard_Integer aNbArrows = 6; const gp_Dir aDirList[6] = { -gp::DX(), gp::DX(), -gp::DY(), gp::DY(), -gp::DZ(), gp::DZ() }; const Prs3d_ToolCylinder aCylTool (mySize * 0.1, 0.0, mySize * 0.2, myNbSplitsArrow, myNbSplitsArrow); Handle(Graphic3d_ArrayOfTriangles) aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(), aNbArrows * aCylTool.TrianglesNb() * 3, Graphic3d_ArrayFlags_VertexNormal); Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2); for (Standard_Integer anArrIter = 0; anArrIter < aNbArrows; ++anArrIter) { const gp_Dir& aDir = aDirList[anArrIter]; const gp_XYZ aPnt = aLightPos + aDir.XYZ() * aLen; if (!aLineArray.IsNull()) { aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 0.5); aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 1.5); } if (!aTrisArray.IsNull()) { const gp_Ax3 aSystem (aPnt + aDir.XYZ() * aLen, -aDir); gp_Trsf aTrsfCone; aTrsfCone.SetTransformation (aSystem, gp_Ax3()); aCylTool.FillArray (aTrisArray, aTrsfCone); } } if (!aLineArray.IsNull()) { Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup(); aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow); aDirGroupShadow->AddPrimitiveArray (aLineArray); } if (!aTrisArray.IsNull()) { Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup(); anArrowGroup->SetClosed (true); anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect()); anArrowGroup->AddPrimitiveArray (aTrisArray); } } { Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1); aPoints->AddVertex (aLightPos); Handle(Graphic3d_Group) aGroup = thePrs->NewGroup(); aGroup->SetGroupPrimitivesAspect (theMode == 1 ? myDrawer->PointAspect()->Aspect() : myDisabledMarkerAspect); aGroup->AddPrimitiveArray (aPoints); } } // ======================================================================= // function : computeDirectional // purpose : // ======================================================================= void AIS_LightSource::computeDirectional (const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { const Standard_Real aDistance = mySize * 0.5; const Standard_Real aStep = aDistance * 0.5; // light source direction is set to local transformation const gp_Dir aLightDir = -gp::DZ(); const gp_XYZ aLightPos = -aStep * aLightDir.XYZ(); Standard_Integer aNbArrows = 1; if (myNbArrows >= 9) { aNbArrows = 9; } else if (myNbArrows >= 5) { aNbArrows = 5; } else if (myNbArrows >= 3) { aNbArrows = 3; } TColgp_Array1OfPnt aPoints (1, aNbArrows); { const gp_Ax2 anAxes (gp::Origin(), aLightDir); const gp_XYZ aDY = anAxes.YDirection().XYZ() * aStep; const gp_XYZ aDX = anAxes.XDirection().XYZ() * aStep; const gp_XYZ aDXY = aDX + aDY; switch (aNbArrows) { case 9: { aPoints.SetValue (6, aLightPos + aDY); aPoints.SetValue (7, aLightPos + aDX); aPoints.SetValue (8, aLightPos - aDY); aPoints.SetValue (9, aLightPos - aDX); } Standard_FALLTHROUGH case 5: { aPoints.SetValue (4, aLightPos - aDY + aDX); aPoints.SetValue (5, aLightPos + aDY - aDX); } Standard_FALLTHROUGH case 3: { aPoints.SetValue (2, aLightPos + aDXY); aPoints.SetValue (3, aLightPos - aDXY); } Standard_FALLTHROUGH case 1: { aPoints.SetValue (1, aLightPos); break; } } } const Prs3d_ToolCylinder aCylTool (aDistance * 0.1, 0.0, aDistance * 0.2, myNbSplitsArrow, myNbSplitsArrow); Handle(Graphic3d_ArrayOfTriangles) aTrisArray; if (theMode == 0) { aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(), aNbArrows * aCylTool.TrianglesNb() * 3, Graphic3d_ArrayFlags_VertexNormal); } Handle(Graphic3d_ArrayOfPoints) aPntArray = new Graphic3d_ArrayOfPoints (aNbArrows); Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2); for (Standard_Integer aPntIter = aPoints.Lower(); aPntIter <= aPoints.Upper(); ++aPntIter) { const gp_Pnt aPnt = aPoints.Value (aPntIter); if (!aPntArray.IsNull()) { aPntArray->AddVertex (aPnt); } if (!aLineArray.IsNull()) { aLineArray->AddVertex (aPnt); aLineArray->AddVertex (gp_Pnt (aPnt.XYZ() + aLightDir.XYZ() * aDistance)); } if (!aTrisArray.IsNull()) { const gp_Ax3 aSystem (aPnt.XYZ() + aLightDir.XYZ() * aDistance, aLightDir); gp_Trsf aTrsfCone; aTrsfCone.SetTransformation (aSystem, gp_Ax3()); aCylTool.FillArray (aTrisArray, aTrsfCone); } } if (!aLineArray.IsNull() && theMode == 0) { Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup(); aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow); aDirGroupShadow->AddPrimitiveArray (aLineArray); } if (!aLineArray.IsNull()) { Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup(); aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect()); aDirGroup->AddPrimitiveArray (aLineArray); } if (!aTrisArray.IsNull()) { Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup(); anArrowGroup->SetClosed (true); anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect()); anArrowGroup->AddPrimitiveArray (aTrisArray); } if (!aPntArray.IsNull()) { Handle(Graphic3d_Group) aGroup = thePrs->NewGroup(); aGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect()); aGroup->AddPrimitiveArray (aPntArray); } { Handle(Graphic3d_ArrayOfPoints) aPntArray2 = new Graphic3d_ArrayOfPoints (1); aPntArray2->AddVertex (aLightPos); Handle(Graphic3d_Group) aGroup = thePrs->NewGroup(); aGroup->SetGroupPrimitivesAspect (myDisabledMarkerAspect); aGroup->AddPrimitiveArray (aPntArray2); } } // ======================================================================= // function : computePositional // purpose : // ======================================================================= void AIS_LightSource::computePositional (const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { // light source position is set to local transformation const gp_XYZ aLightPos = gp::Origin().XYZ(); const Standard_Real aRadius = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : 0.0; if (theMode == 0 && aRadius > 0.0 && myToDisplayRange) { Handle(Graphic3d_ArrayOfTriangles) aPosRangeArray = Prs3d_ToolSphere::Create (aRadius, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf()); Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup(); aRangeGroup->SetClosed (true); aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect()); aRangeGroup->AddPrimitiveArray (aPosRangeArray); } { Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1); aPoints->AddVertex (aLightPos); Handle(Graphic3d_Group) aGroup = thePrs->NewGroup(); aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect()); aGroup->AddPrimitiveArray (aPoints); } } // ======================================================================= // function : computeSpot // purpose : // ======================================================================= void AIS_LightSource::computeSpot (const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode) { // light source position and direction are set to local transformation const gp_Dir aLightDir = -gp::DZ(); const gp_XYZ aLightPos = gp::Origin().XYZ(); const Standard_Real aDistance = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : mySize; { Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1); aPoints->AddVertex (aLightPos); Handle(Graphic3d_Group) aGroup = thePrs->NewGroup(); aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect()); aGroup->AddPrimitiveArray (aPoints); } { Handle(Graphic3d_ArrayOfSegments) aDirArray = new Graphic3d_ArrayOfSegments (2); aDirArray->AddVertex (aLightPos); aDirArray->AddVertex (gp_Pnt (aLightPos + aLightDir.XYZ() * aDistance)); Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup(); aDirGroupShadow->SetClosed (true); aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow); aDirGroupShadow->AddPrimitiveArray (aDirArray); Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup(); aDirGroup->SetClosed (true); aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect()); aDirGroup->AddPrimitiveArray (aDirArray); } if (theMode == 0 && myToDisplayRange) { const Standard_ShortReal aHalfAngle = myLightSource->Angle() / 2.0f; const Standard_Real aRadius = aDistance * Tan (aHalfAngle); gp_Ax3 aSystem (aLightPos + aLightDir.XYZ() * aDistance, -aLightDir); gp_Trsf aTrsfCone; aTrsfCone.SetTransformation (aSystem, gp_Ax3()); Handle(Graphic3d_ArrayOfTriangles) aSpotRangeArray = Prs3d_ToolCylinder::Create (aRadius, 0.0, aDistance, myNbSplitsQuadric, myNbSplitsQuadric, aTrsfCone); Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup(); aRangeGroup->SetClosed (true); aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect()); aRangeGroup->AddPrimitiveArray (aSpotRangeArray); } } // ======================================================================= // function : ComputeSelection // purpose : // ======================================================================= void AIS_LightSource::ComputeSelection (const Handle(SelectMgr_Selection)& theSel, const Standard_Integer theMode) { if (theMode != 0) { return; } Handle(AIS_LightSourceOwner) anEntityOwner = new AIS_LightSourceOwner (this, 15); { Handle(Select3D_SensitivePoint) aSensPosition = new Select3D_SensitivePoint (anEntityOwner, gp::Origin()); aSensPosition->SetSensitivityFactor (12); if (!myTransformPersistence.IsNull() && myTransformPersistence->IsTrihedronOr2d()) { aSensPosition->SetSensitivityFactor (Max (12, Standard_Integer (mySize * 0.5))); } theSel->Add (aSensPosition); } }