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 <gp_Quaternion.hxx>
20 #include <Graphic3d_ArrayOfPoints.hxx>
21 #include <Graphic3d_ArrayOfPolylines.hxx>
22 #include <Graphic3d_ArrayOfSegments.hxx>
23 #include <Graphic3d_CView.hxx>
24 #include <Graphic3d_Group.hxx>
25 #include <Prs3d_ArrowAspect.hxx>
26 #include <Prs3d_PointAspect.hxx>
27 #include <Prs3d_Text.hxx>
28 #include <Prs3d_ToolCylinder.hxx>
29 #include <Prs3d_ToolSphere.hxx>
30 #include <Select3D_SensitivePoint.hxx>
31 #include <Select3D_SensitiveSphere.hxx>
32 #include <V3d_View.hxx>
34 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource, AIS_InteractiveObject)
35 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSourceOwner, SelectMgr_EntityOwner)
37 // =======================================================================
38 // function : AIS_LightSourceOwner
40 // =======================================================================
41 AIS_LightSourceOwner::AIS_LightSourceOwner (const Handle(AIS_LightSource)& theObject,
42 Standard_Integer thePriority)
43 : SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)&)theObject, thePriority)
48 // =======================================================================
49 // function : HandleMouseClick
51 // =======================================================================
52 Standard_Boolean AIS_LightSourceOwner::HandleMouseClick (const Graphic3d_Vec2i& ,
53 Aspect_VKeyMouse theKey,
54 Aspect_VKeyFlags theFlags,
57 AIS_LightSource* aLightSource = dynamic_cast<AIS_LightSource*>(mySelectable);
58 if (aLightSource != NULL
59 && aLightSource->ToSwitchOnClick()
60 && theKey == Aspect_VKeyMouse_LeftButton
61 && theFlags == Aspect_VKeyFlags_NONE)
63 aLightSource->Light()->SetEnabled (!aLightSource->Light()->IsEnabled());
64 aLightSource->updateLightAspects();
70 //=======================================================================
71 //function : HilightWithColor
73 //=======================================================================
74 void AIS_LightSourceOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager)& thePM,
75 const Handle(Prs3d_Drawer)& theStyle,
76 const Standard_Integer theMode)
78 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (mySelectable);
79 if (aLightSource.IsNull())
84 if (aLightSource->Light()->Type() == Graphic3d_TypeOfLightSource_Directional && aLightSource->myIsDraggable)
86 Handle(Prs3d_Presentation) aPrs = aLightSource->GetHilightPresentation (thePM);
87 const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
89 : (thePM->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : aLightSource->ZLayer());
91 if (aPrs->GetZLayer() != aZLayer)
93 aPrs->SetZLayer (aZLayer);
95 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
96 const gp_Pnt aDetPnt = aLightSource->mySensSphere->LastDetectedPoint();
97 if (aDetPnt.X() == RealLast())
101 aPoints->AddVertex (aDetPnt);
102 Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
103 const Handle(Prs3d_PointAspect) aPointAspect = new Prs3d_PointAspect (Aspect_TOM_O_POINT, theStyle->Color(), 3.0f);
104 aGroup->SetGroupPrimitivesAspect (aPointAspect->Aspect());
105 aGroup->AddPrimitiveArray (aPoints);
107 const Standard_Real aRadius = aLightSource->Size() * 0.5;
108 const Standard_Integer aNbPnts = int (aLightSource->ArcSize() * 180 / (M_PI * aRadius));
109 TColgp_Array1OfPnt aCircPoints (0, aNbPnts);
110 const gp_Dir aDirNorm (gp_Vec (gp::Origin(), aDetPnt));
111 gp_Dir aDirNormToPln (gp::DY());
112 if (!gp::DX().IsParallel (aDirNorm, Precision::Angular()))
114 aDirNormToPln = gp::DX().Crossed (aDirNorm);
116 for (Standard_Integer aStep = 0; aStep < aNbPnts; ++aStep)
118 aCircPoints.SetValue (aStep, (aDetPnt.Rotated (gp_Ax1 (gp::Origin(), aDirNormToPln), M_PI / 90 * (aStep - aNbPnts / 2))));
121 Handle(Graphic3d_Group) aCircGroup = aPrs->NewGroup();
122 Handle(Graphic3d_ArrayOfPolylines) aPolylines = new Graphic3d_ArrayOfPolylines (aNbPnts * 2, 2);
123 aPolylines->AddBound (aNbPnts);
125 for (Standard_Integer anIdx = 0; anIdx < aNbPnts; ++anIdx)
127 aPolylines->AddVertex (aCircPoints.Value (anIdx).Rotated (gp_Ax1 (gp::Origin(), aDirNorm), M_PI / 2));
129 aPolylines->AddBound (aNbPnts);
130 for (Standard_Integer anIdx = 0; anIdx < aNbPnts; ++anIdx)
132 aPolylines->AddVertex (aCircPoints.Value (anIdx));
134 aCircGroup->AddPrimitiveArray (aPolylines, Standard_False);
135 aCircGroup->SetGroupPrimitivesAspect (theStyle->ArrowAspect()->Aspect());
136 if (thePM->IsImmediateModeOn())
138 thePM->AddToImmediateList (aPrs);
147 base_type::HilightWithColor (thePM, theStyle, theMode);;
151 //=======================================================================
152 //function : IsForcedHilight
154 //=======================================================================
155 Standard_Boolean AIS_LightSourceOwner::IsForcedHilight() const
157 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (mySelectable);
158 if (aLightSource.IsNull())
160 return Standard_False;
162 if (aLightSource->Light()->Type() == Graphic3d_TypeOfLightSource_Directional)
164 return Standard_True;
166 return Standard_False;
169 // =======================================================================
170 // function : Constructor
172 // =======================================================================
173 AIS_LightSource::AIS_LightSource (const Handle(Graphic3d_CLight)& theLight)
174 : myLightSource (theLight),
175 myCodirMarkerType (Aspect_TOM_X),
176 myOpposMarkerType (Aspect_TOM_O_POINT),
179 myNbSplitsQuadric (theLight->Type() == Graphic3d_TypeOfLightSource_Ambient ? 10 : 30),
180 myNbSplitsArrow (20),
181 mySensSphereArcSize (25),
182 myIsZoomable (theLight->Type() == Graphic3d_TypeOfLightSource_Positional
183 || theLight->Type() == Graphic3d_TypeOfLightSource_Spot),
184 myIsDraggable (theLight->Type() == Graphic3d_TypeOfLightSource_Directional),
185 myToDisplayName (true),
186 myToDisplayRange (true),
187 myToSwitchOnClick (true)
189 myMarkerTypes[0] = Aspect_TOM_O_X;
190 myMarkerTypes[1] = Aspect_TOM_O_POINT;
192 myInfiniteState = true;
194 const Quantity_Color aColor = theLight->Color();
195 myDrawer->SetPointAspect (new Prs3d_PointAspect (myMarkerTypes[1], aColor, 3.0f));
196 myDisabledMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_EMPTY, aColor, 3.0f);
198 Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_UserDefined);
199 aMat.SetColor (aColor);
200 myDrawer->SetArrowAspect (new Prs3d_ArrowAspect());
201 myDrawer->ArrowAspect()->SetColor (aColor);
202 myDrawer->ArrowAspect()->Aspect()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
203 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial() = aMat;
204 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (Aspect_TOM_EMPTY);
205 myDrawer->ArrowAspect()->Aspect()->SetMarkerScale (2.0f);
206 myArrowLineAspectShadow = new Graphic3d_AspectLine3d (Quantity_NOC_BLACK, Aspect_TOL_SOLID,
207 theLight->Type() != Graphic3d_TypeOfLightSource_Ambient ? 3.0f : 1.0f);
209 myDrawer->SetupOwnShadingAspect();
210 myDrawer->ShadingAspect()->SetColor (aColor);
211 myDrawer->ShadingAspect()->SetMaterial (aMat);
212 myDrawer->ShadingAspect()->SetTransparency (0.5f);
213 myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
215 myDrawer->SetTextAspect (new Prs3d_TextAspect());
216 myDrawer->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
217 myDrawer->TextAspect()->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
218 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_LEFT);
219 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOPFIRSTLINE);
221 updateLightTransformPersistence();
223 myDrawer->SetDisplayMode (0);
224 myDynHilightDrawer = new Prs3d_Drawer();
225 myDynHilightDrawer->Link (myDrawer);
226 myDynHilightDrawer->SetDisplayMode (1);
227 myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
229 if (!myTransformPersistence.IsNull()
230 && myTransformPersistence->IsTrihedronOr2d())
232 myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
233 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
234 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_CENTER);
235 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOP);
239 //=======================================================================
240 //function : ProcessDragging
242 //=======================================================================
243 Standard_Boolean AIS_LightSource::ProcessDragging (const Handle(AIS_InteractiveContext)& theCtx,
244 const Handle(V3d_View)& theView,
245 const Handle(SelectMgr_EntityOwner)& theOwner,
246 const Graphic3d_Vec2i& theDragFrom,
247 const Graphic3d_Vec2i& theDragTo,
248 const AIS_DragAction theAction)
250 if (Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
252 return Standard_False;
257 case AIS_DragAction_Start:
259 myLocTrsfStart = LocalTransformation();
260 return Standard_True;
262 case AIS_DragAction_Confirmed:
264 return Standard_True;
266 case AIS_DragAction_Update:
268 mySensSphere->ResetLastDetectedPoint();
269 SetLocalTransformation (myLocTrsfStart);
270 theCtx->MainSelector()->Pick (theDragFrom.x(), theDragFrom.y(), theView);
271 gp_Pnt aStartPosition = mySensSphere->LastDetectedPoint();
273 mySensSphere->ResetLastDetectedPoint();
274 theCtx->MainSelector()->Pick (theDragTo.x(), theDragTo.y(), theView);
275 gp_Pnt aCurrPosition = mySensSphere->LastDetectedPoint();
276 if (aCurrPosition.X() != RealLast()
277 && aStartPosition.Distance (aCurrPosition) > Precision::Confusion())
280 aQRot.SetRotation (gp_Vec (gp_Pnt (0, 0, 0), aStartPosition), gp_Vec (gp_Pnt (0, 0, 0), aCurrPosition));
282 aTrsf.SetRotation (aQRot);
283 SetLocalTransformation (myLocTrsfStart * aTrsf);
284 const Standard_Integer aHiMod = HasHilightMode() ? HilightMode() : 0;
285 theOwner->UpdateHighlightTrsf (theCtx->CurrentViewer(), theCtx->MainPrsMgr(), aHiMod);
287 return Standard_True;
289 case AIS_DragAction_Abort:
291 return Standard_True;
293 case AIS_DragAction_Stop:
295 GetHilightPresentation (theCtx->MainPrsMgr())->Clear();
299 return Standard_False;
302 // =======================================================================
303 // function : updateLightAspects
305 // =======================================================================
306 void AIS_LightSource::updateLightAspects()
308 const Quantity_Color aBaseColor = myLightSource->Color();
309 const Quantity_Color aDimColor (aBaseColor.Rgb() * 0.3f);
310 const Quantity_Color aColor = myLightSource->IsEnabled() ? aBaseColor : aDimColor;
311 myDrawer->PointAspect()->SetColor (aColor);
312 myDrawer->PointAspect()->Aspect()->SetMarkerType (MarkerType (myLightSource->IsEnabled()));
313 myDrawer->PointAspect()->Aspect()->SetMarkerImage(MarkerImage(myLightSource->IsEnabled()));
315 myDisabledMarkerAspect->SetColor (aColor);
316 myDisabledMarkerAspect->SetMarkerScale(myDrawer->PointAspect()->Aspect()->MarkerScale());
317 myDisabledMarkerAspect->SetMarkerType (myLightSource->IsEnabled() ? Aspect_TOM_EMPTY : MarkerType (false));
318 myDisabledMarkerAspect->SetMarkerImage(MarkerImage (false));
320 myDrawer->ShadingAspect()->SetColor (aColor);
321 myDrawer->ArrowAspect() ->SetColor (aColor);
322 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial().SetColor (aColor);
324 if (myLightSource->Type() == Graphic3d_TypeOfLightSource_Directional)
326 const Standard_Real anAngleTol = 2.0 * M_PI / 180.0;
327 Aspect_TypeOfMarker aDirMark = Aspect_TOM_EMPTY;
328 if (myLightSource->IsEnabled()
329 && myLightSource->IsHeadlight()
330 && myLightSource->Direction().IsParallel (gp::DZ(), anAngleTol))
332 aDirMark = myLightSource->Direction().IsOpposite (-gp::DZ(), anAngleTol) ? myOpposMarkerType : myCodirMarkerType;
334 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (aDirMark);
336 SynchronizeAspects();
339 // =======================================================================
340 // function : updateLightTransformPersistence
342 // =======================================================================
343 void AIS_LightSource::updateLightTransformPersistence()
345 Handle(Graphic3d_TransformPers) aTrsfPers = myTransformPersistence;
346 switch (myLightSource->Type())
348 case Graphic3d_TypeOfLightSource_Ambient:
352 if (aTrsfPers.IsNull() || !aTrsfPers->IsTrihedronOr2d())
354 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
363 case Graphic3d_TypeOfLightSource_Directional:
365 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers;
368 aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : Graphic3d_TMF_None;
370 if (aMode != Graphic3d_TMF_None)
372 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
374 if (aMode == Graphic3d_TMF_CameraPers)
376 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
380 aTrsfPers = new Graphic3d_TransformPers (aMode, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
390 case Graphic3d_TypeOfLightSource_Positional:
391 case Graphic3d_TypeOfLightSource_Spot:
393 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight()
394 ? Graphic3d_TMF_CameraPers
395 : (!myIsZoomable ? Graphic3d_TMF_ZoomPers : Graphic3d_TMF_None);
396 if (aMode != Graphic3d_TMF_None)
398 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
400 if (aMode == Graphic3d_TMF_CameraPers)
402 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
406 aTrsfPers = new Graphic3d_TransformPers (aMode, myLightSource->Position());
409 if (aMode == Graphic3d_TMF_ZoomPers)
411 aTrsfPers->SetAnchorPoint (myLightSource->Position());
422 SetTransformPersistence (aTrsfPers);
425 // =======================================================================
426 // function : updateLightLocalTransformation
428 // =======================================================================
429 void AIS_LightSource::updateLightLocalTransformation()
431 myLocalTransformation.Nullify();
432 switch (myLightSource->Type())
434 case Graphic3d_TypeOfLightSource_Ambient:
439 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
440 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
444 case Graphic3d_TypeOfLightSource_Directional:
446 const gp_Pnt aLightPos = (myIsZoomable && !myLightSource->IsHeadlight())
447 ? myLightSource->DisplayPosition()
450 const gp_Ax2 anAx2 (aLightPos, -myLightSource->Direction());
451 aTrsf.SetTransformation (anAx2, gp_Ax3());
452 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
455 case Graphic3d_TypeOfLightSource_Positional:
460 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
461 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
465 case Graphic3d_TypeOfLightSource_Spot:
468 const gp_Ax2 anAx2 (myIsZoomable ? myLightSource->Position() : gp::Origin(), -myLightSource->Direction());
469 aTrsf.SetTransformation (anAx2, gp_Ax3());
470 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
474 UpdateTransformation();
477 // =======================================================================
478 // function : setLocalTransformation
480 // =======================================================================
481 void AIS_LightSource::setLocalTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
483 const gp_Trsf aTrsf = !theTrsf.IsNull() ? theTrsf->Transformation() : gp_Trsf();
484 switch (myLightSource->Type())
486 case Graphic3d_TypeOfLightSource_Ambient:
490 case Graphic3d_TypeOfLightSource_Directional:
492 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
493 myLightSource->SetDirection (aNewDir);
496 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
497 myLightSource->SetDisplayPosition (aNewPos);
501 case Graphic3d_TypeOfLightSource_Positional:
503 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
504 myLightSource->SetPosition (aNewPos);
507 case Graphic3d_TypeOfLightSource_Spot:
509 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
510 myLightSource->SetPosition (aNewPos);
512 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
513 myLightSource->SetDirection (aNewDir);
518 base_type::setLocalTransformation (new TopLoc_Datum3D (aTrsf));
520 updateLightAspects();
521 updateLightTransformPersistence();
524 // =======================================================================
525 // function : Compute
527 // =======================================================================
528 void AIS_LightSource::Compute (const Handle(PrsMgr_PresentationManager)& ,
529 const Handle(Prs3d_Presentation)& thePrs,
530 const Standard_Integer theMode)
532 thePrs->SetInfiniteState (myInfiniteState);
541 updateLightAspects();
542 updateLightTransformPersistence();
543 updateLightLocalTransformation();
546 switch (myLightSource->Type())
548 case Graphic3d_TypeOfLightSource_Ambient: computeAmbient (thePrs, theMode); break;
549 case Graphic3d_TypeOfLightSource_Directional: computeDirectional(thePrs, theMode); break;
550 case Graphic3d_TypeOfLightSource_Positional: computePositional (thePrs, theMode); break;
551 case Graphic3d_TypeOfLightSource_Spot: computeSpot (thePrs, theMode); break;
556 TCollection_AsciiString aPrefix = !myTransformPersistence.IsNull()
557 && myTransformPersistence->IsTrihedronOr2d()
559 TCollection_AsciiString aName = aPrefix + myLightSource->Name();
560 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), aName, gp::Origin());
564 // =======================================================================
565 // function : computeAmbient
567 // =======================================================================
568 void AIS_LightSource::computeAmbient (const Handle(Prs3d_Presentation)& thePrs,
569 const Standard_Integer theMode)
571 const gp_XYZ aLightPos = gp::Origin().XYZ();
574 Handle(Graphic3d_ArrayOfTriangles) aSphereArray = Prs3d_ToolSphere::Create (mySize * 0.25, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
575 Handle(Graphic3d_Group) aSphereGroup = thePrs->NewGroup();
576 aSphereGroup->SetClosed (true);
577 aSphereGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
578 aSphereGroup->AddPrimitiveArray (aSphereArray);
583 const Standard_Real aLen = mySize * 0.25;
584 const Standard_Integer aNbArrows = 6;
585 const gp_Dir aDirList[6] = { -gp::DX(), gp::DX(), -gp::DY(), gp::DY(), -gp::DZ(), gp::DZ() };
587 const Prs3d_ToolCylinder aCylTool (mySize * 0.1, 0.0, mySize * 0.2, myNbSplitsArrow, myNbSplitsArrow);
588 Handle(Graphic3d_ArrayOfTriangles) aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
589 aNbArrows * aCylTool.TrianglesNb() * 3,
590 Graphic3d_ArrayFlags_VertexNormal);
591 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
592 for (Standard_Integer anArrIter = 0; anArrIter < aNbArrows; ++anArrIter)
594 const gp_Dir& aDir = aDirList[anArrIter];
595 const gp_XYZ aPnt = aLightPos + aDir.XYZ() * aLen;
596 if (!aLineArray.IsNull())
598 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 0.5);
599 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 1.5);
601 if (!aTrisArray.IsNull())
603 const gp_Ax3 aSystem (aPnt + aDir.XYZ() * aLen, -aDir);
605 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
606 aCylTool.FillArray (aTrisArray, aTrsfCone);
610 if (!aLineArray.IsNull())
612 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
613 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
614 aDirGroupShadow->AddPrimitiveArray (aLineArray);
616 if (!aTrisArray.IsNull())
618 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
619 anArrowGroup->SetClosed (true);
620 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
621 anArrowGroup->AddPrimitiveArray (aTrisArray);
626 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
627 aPoints->AddVertex (aLightPos);
628 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
629 aGroup->SetGroupPrimitivesAspect (theMode == 1 ? myDrawer->PointAspect()->Aspect() : myDisabledMarkerAspect);
630 aGroup->AddPrimitiveArray (aPoints);
634 // =======================================================================
635 // function : computeDirectional
637 // =======================================================================
638 void AIS_LightSource::computeDirectional (const Handle(Prs3d_Presentation)& thePrs,
639 const Standard_Integer theMode)
641 const Standard_Real aDistance = mySize * 0.5;
642 const Standard_Real aStep = aDistance * 0.5;
644 // light source direction is set to local transformation
645 const gp_Dir aLightDir = -gp::DZ();
646 const gp_XYZ aLightPos = -aStep * aLightDir.XYZ();
648 Standard_Integer aNbArrows = 1;
649 if (myNbArrows >= 9) { aNbArrows = 9; }
650 else if (myNbArrows >= 5) { aNbArrows = 5; }
651 else if (myNbArrows >= 3) { aNbArrows = 3; }
652 TColgp_Array1OfPnt aPoints (1, aNbArrows);
654 const gp_Ax2 anAxes (gp::Origin(), aLightDir);
655 const gp_XYZ aDY = anAxes.YDirection().XYZ() * aStep;
656 const gp_XYZ aDX = anAxes.XDirection().XYZ() * aStep;
657 const gp_XYZ aDXY = aDX + aDY;
662 aPoints.SetValue (6, aLightPos + aDY);
663 aPoints.SetValue (7, aLightPos + aDX);
664 aPoints.SetValue (8, aLightPos - aDY);
665 aPoints.SetValue (9, aLightPos - aDX);
670 aPoints.SetValue (4, aLightPos - aDY + aDX);
671 aPoints.SetValue (5, aLightPos + aDY - aDX);
676 aPoints.SetValue (2, aLightPos + aDXY);
677 aPoints.SetValue (3, aLightPos - aDXY);
682 aPoints.SetValue (1, aLightPos);
688 const Prs3d_ToolCylinder aCylTool (aDistance * 0.1, 0.0, aDistance * 0.2, myNbSplitsArrow, myNbSplitsArrow);
689 Handle(Graphic3d_ArrayOfTriangles) aTrisArray;
692 aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
693 aNbArrows * aCylTool.TrianglesNb() * 3,
694 Graphic3d_ArrayFlags_VertexNormal);
696 Handle(Graphic3d_ArrayOfPoints) aPntArray = new Graphic3d_ArrayOfPoints (aNbArrows);
697 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
698 for (Standard_Integer aPntIter = aPoints.Lower(); aPntIter <= aPoints.Upper(); ++aPntIter)
700 const gp_Pnt aPnt = aPoints.Value (aPntIter);
701 if (!aPntArray.IsNull())
703 aPntArray->AddVertex (aPnt);
705 if (!aLineArray.IsNull())
707 aLineArray->AddVertex (aPnt);
708 aLineArray->AddVertex (gp_Pnt (aPnt.XYZ() + aLightDir.XYZ() * aDistance));
710 if (!aTrisArray.IsNull())
712 const gp_Ax3 aSystem (aPnt.XYZ() + aLightDir.XYZ() * aDistance, aLightDir);
714 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
715 aCylTool.FillArray (aTrisArray, aTrsfCone);
719 if (!aLineArray.IsNull() && theMode == 0)
721 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
722 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
723 aDirGroupShadow->AddPrimitiveArray (aLineArray);
725 if (!aLineArray.IsNull())
727 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
728 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
729 aDirGroup->AddPrimitiveArray (aLineArray);
731 if (!aTrisArray.IsNull())
733 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
734 anArrowGroup->SetClosed (true);
735 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
736 anArrowGroup->AddPrimitiveArray (aTrisArray);
738 if (!aPntArray.IsNull())
740 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
741 aGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
742 aGroup->AddPrimitiveArray (aPntArray);
745 Handle(Graphic3d_ArrayOfPoints) aPntArray2 = new Graphic3d_ArrayOfPoints (1);
746 aPntArray2->AddVertex (aLightPos);
747 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
748 aGroup->SetGroupPrimitivesAspect (myDisabledMarkerAspect);
749 aGroup->AddPrimitiveArray (aPntArray2);
753 // =======================================================================
754 // function : computePositional
756 // =======================================================================
757 void AIS_LightSource::computePositional (const Handle(Prs3d_Presentation)& thePrs,
758 const Standard_Integer theMode)
760 // light source position is set to local transformation
761 const gp_XYZ aLightPos = gp::Origin().XYZ();
762 const Standard_Real aRadius = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : 0.0;
767 Handle(Graphic3d_ArrayOfTriangles) aPosRangeArray = Prs3d_ToolSphere::Create (aRadius, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
768 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
769 aRangeGroup->SetClosed (true);
770 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
771 aRangeGroup->AddPrimitiveArray (aPosRangeArray);
774 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
775 aPoints->AddVertex (aLightPos);
776 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
777 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
778 aGroup->AddPrimitiveArray (aPoints);
782 // =======================================================================
783 // function : computeSpot
785 // =======================================================================
786 void AIS_LightSource::computeSpot (const Handle(Prs3d_Presentation)& thePrs,
787 const Standard_Integer theMode)
789 // light source position and direction are set to local transformation
790 const gp_Dir aLightDir = -gp::DZ();
791 const gp_XYZ aLightPos = gp::Origin().XYZ();
792 const Standard_Real aDistance = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : mySize;
794 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
795 aPoints->AddVertex (aLightPos);
797 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
798 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
799 aGroup->AddPrimitiveArray (aPoints);
803 Handle(Graphic3d_ArrayOfSegments) aDirArray = new Graphic3d_ArrayOfSegments (2);
804 aDirArray->AddVertex (aLightPos);
805 aDirArray->AddVertex (gp_Pnt (aLightPos + aLightDir.XYZ() * aDistance));
807 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
808 aDirGroupShadow->SetClosed (true);
809 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
810 aDirGroupShadow->AddPrimitiveArray (aDirArray);
812 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
813 aDirGroup->SetClosed (true);
814 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
815 aDirGroup->AddPrimitiveArray (aDirArray);
821 const Standard_ShortReal aHalfAngle = myLightSource->Angle() / 2.0f;
822 const Standard_Real aRadius = aDistance * Tan (aHalfAngle);
823 gp_Ax3 aSystem (aLightPos + aLightDir.XYZ() * aDistance, -aLightDir);
825 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
826 Handle(Graphic3d_ArrayOfTriangles) aSpotRangeArray = Prs3d_ToolCylinder::Create (aRadius, 0.0, aDistance,
827 myNbSplitsQuadric, myNbSplitsQuadric, aTrsfCone);
829 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
830 aRangeGroup->SetClosed (true);
831 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
832 aRangeGroup->AddPrimitiveArray (aSpotRangeArray);
836 // =======================================================================
837 // function : ComputeSelection
839 // =======================================================================
840 void AIS_LightSource::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
841 const Standard_Integer theMode)
848 Handle(AIS_LightSourceOwner) anEntityOwner = new AIS_LightSourceOwner (this, 15);
850 if (myLightSource->Type() == Graphic3d_TypeOfLightSource_Directional)
852 mySensSphere = new Select3D_SensitiveSphere (anEntityOwner, gp::Origin(), mySize * 0.5);
853 theSel->Add (mySensSphere);
856 Handle(Select3D_SensitivePoint) aSensPosition = new Select3D_SensitivePoint (anEntityOwner, gp::Origin());
857 aSensPosition->SetSensitivityFactor (12);
858 if (!myTransformPersistence.IsNull()
859 && myTransformPersistence->IsTrihedronOr2d())
861 aSensPosition->SetSensitivityFactor (Max (12, Standard_Integer (mySize * 0.5)));
863 theSel->Add (aSensPosition);