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 <gp_Quaternion.hxx>
20 #include <Graphic3d_ArrayOfPoints.hxx>
21 #include <Graphic3d_ArrayOfPolylines.hxx>
22 #include <Graphic3d_ArrayOfSegments.hxx>
23 #include <Graphic3d_ArrayOfTriangles.hxx>
24 #include <Graphic3d_CView.hxx>
25 #include <Graphic3d_Group.hxx>
26 #include <Prs3d_ArrowAspect.hxx>
27 #include <Prs3d_PointAspect.hxx>
28 #include <Prs3d_Text.hxx>
29 #include <Prs3d_ToolCylinder.hxx>
30 #include <Prs3d_ToolSphere.hxx>
31 #include <Select3D_SensitivePoint.hxx>
32 #include <Select3D_SensitiveSphere.hxx>
33 #include <V3d_View.hxx>
34
IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource,AIS_InteractiveObject)35 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSource, AIS_InteractiveObject)
36 IMPLEMENT_STANDARD_RTTIEXT(AIS_LightSourceOwner, SelectMgr_EntityOwner)
37
38 // =======================================================================
39 // function : AIS_LightSourceOwner
40 // purpose :
41 // =======================================================================
42 AIS_LightSourceOwner::AIS_LightSourceOwner (const Handle(AIS_LightSource)& theObject,
43 Standard_Integer thePriority)
44 : SelectMgr_EntityOwner ((const Handle(SelectMgr_SelectableObject)&)theObject, thePriority)
45 {
46 //
47 }
48
49 // =======================================================================
50 // function : HandleMouseClick
51 // purpose :
52 // =======================================================================
HandleMouseClick(const Graphic3d_Vec2i &,Aspect_VKeyMouse theKey,Aspect_VKeyFlags theFlags,bool)53 Standard_Boolean AIS_LightSourceOwner::HandleMouseClick (const Graphic3d_Vec2i& ,
54 Aspect_VKeyMouse theKey,
55 Aspect_VKeyFlags theFlags,
56 bool )
57 {
58 AIS_LightSource* aLightSource = dynamic_cast<AIS_LightSource*>(mySelectable);
59 if (aLightSource != NULL
60 && aLightSource->ToSwitchOnClick()
61 && theKey == Aspect_VKeyMouse_LeftButton
62 && theFlags == Aspect_VKeyFlags_NONE)
63 {
64 aLightSource->Light()->SetEnabled (!aLightSource->Light()->IsEnabled());
65 aLightSource->updateLightAspects();
66 return true;
67 }
68 return false;
69 }
70
71 //=======================================================================
72 //function : HilightWithColor
73 //purpose :
74 //=======================================================================
HilightWithColor(const Handle (PrsMgr_PresentationManager)& thePM,const Handle (Prs3d_Drawer)& theStyle,const Standard_Integer theMode)75 void AIS_LightSourceOwner::HilightWithColor (const Handle(PrsMgr_PresentationManager)& thePM,
76 const Handle(Prs3d_Drawer)& theStyle,
77 const Standard_Integer theMode)
78 {
79 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (mySelectable);
80 if (aLightSource.IsNull())
81 {
82 return;
83 }
84
85 if (aLightSource->Light()->Type() == Graphic3d_TypeOfLightSource_Directional && aLightSource->myIsDraggable)
86 {
87 Handle(Prs3d_Presentation) aPrs = aLightSource->GetHilightPresentation (thePM);
88 const Graphic3d_ZLayerId aZLayer = theStyle->ZLayer() != -1
89 ? theStyle->ZLayer()
90 : (thePM->IsImmediateModeOn() ? Graphic3d_ZLayerId_Top : aLightSource->ZLayer());
91 aPrs->Clear();
92 if (aPrs->GetZLayer() != aZLayer)
93 {
94 aPrs->SetZLayer (aZLayer);
95 }
96 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
97 const gp_Pnt aDetPnt = aLightSource->mySensSphere->LastDetectedPoint();
98 if (aDetPnt.X() == RealLast())
99 {
100 return;
101 }
102 aPoints->AddVertex (aDetPnt);
103 Handle(Graphic3d_Group) aGroup = aPrs->NewGroup();
104 const Handle(Prs3d_PointAspect) aPointAspect = new Prs3d_PointAspect (Aspect_TOM_O_POINT, theStyle->Color(), 3.0f);
105 aGroup->SetGroupPrimitivesAspect (aPointAspect->Aspect());
106 aGroup->AddPrimitiveArray (aPoints);
107
108 const Standard_Real aRadius = aLightSource->Size() * 0.5;
109 const Standard_Integer aNbPnts = int (aLightSource->ArcSize() * 180 / (M_PI * aRadius));
110 TColgp_Array1OfPnt aCircPoints (0, aNbPnts);
111 const gp_Dir aDirNorm (gp_Vec (gp::Origin(), aDetPnt));
112 gp_Dir aDirNormToPln (gp::DY());
113 if (!gp::DX().IsParallel (aDirNorm, Precision::Angular()))
114 {
115 aDirNormToPln = gp::DX().Crossed (aDirNorm);
116 }
117 for (Standard_Integer aStep = 0; aStep < aNbPnts; ++aStep)
118 {
119 aCircPoints.SetValue (aStep, (aDetPnt.Rotated (gp_Ax1 (gp::Origin(), aDirNormToPln), M_PI / 90 * (aStep - aNbPnts / 2))));
120 }
121
122 Handle(Graphic3d_Group) aCircGroup = aPrs->NewGroup();
123 Handle(Graphic3d_ArrayOfPolylines) aPolylines = new Graphic3d_ArrayOfPolylines (aNbPnts * 2, 2);
124 aPolylines->AddBound (aNbPnts);
125
126 for (Standard_Integer anIdx = 0; anIdx < aNbPnts; ++anIdx)
127 {
128 aPolylines->AddVertex (aCircPoints.Value (anIdx).Rotated (gp_Ax1 (gp::Origin(), aDirNorm), M_PI / 2));
129 }
130 aPolylines->AddBound (aNbPnts);
131 for (Standard_Integer anIdx = 0; anIdx < aNbPnts; ++anIdx)
132 {
133 aPolylines->AddVertex (aCircPoints.Value (anIdx));
134 }
135 aCircGroup->AddPrimitiveArray (aPolylines, Standard_False);
136 aCircGroup->SetGroupPrimitivesAspect (theStyle->ArrowAspect()->Aspect());
137 if (thePM->IsImmediateModeOn())
138 {
139 thePM->AddToImmediateList (aPrs);
140 }
141 else
142 {
143 aPrs->Display();
144 }
145 }
146 else
147 {
148 base_type::HilightWithColor (thePM, theStyle, theMode);;
149 }
150 }
151
152 //=======================================================================
153 //function : IsForcedHilight
154 //purpose :
155 //=======================================================================
IsForcedHilight() const156 Standard_Boolean AIS_LightSourceOwner::IsForcedHilight() const
157 {
158 Handle(AIS_LightSource) aLightSource = Handle(AIS_LightSource)::DownCast (mySelectable);
159 if (aLightSource.IsNull())
160 {
161 return Standard_False;
162 }
163 if (aLightSource->Light()->Type() == Graphic3d_TypeOfLightSource_Directional)
164 {
165 return Standard_True;
166 }
167 return Standard_False;
168 }
169
170 // =======================================================================
171 // function : Constructor
172 // purpose :
173 // =======================================================================
AIS_LightSource(const Handle (Graphic3d_CLight)& theLight)174 AIS_LightSource::AIS_LightSource (const Handle(Graphic3d_CLight)& theLight)
175 : myLightSource (theLight),
176 myCodirMarkerType (Aspect_TOM_X),
177 myOpposMarkerType (Aspect_TOM_O_POINT),
178 mySize (50),
179 myNbArrows (5),
180 myNbSplitsQuadric (theLight->Type() == Graphic3d_TypeOfLightSource_Ambient ? 10 : 30),
181 myNbSplitsArrow (20),
182 mySensSphereArcSize (25),
183 myIsZoomable (theLight->Type() == Graphic3d_TypeOfLightSource_Positional
184 || theLight->Type() == Graphic3d_TypeOfLightSource_Spot),
185 myIsDraggable (theLight->Type() == Graphic3d_TypeOfLightSource_Directional),
186 myToDisplayName (true),
187 myToDisplayRange (true),
188 myToSwitchOnClick (true)
189 {
190 myMarkerTypes[0] = Aspect_TOM_O_X;
191 myMarkerTypes[1] = Aspect_TOM_O_POINT;
192
193 myInfiniteState = true;
194
195 const Quantity_Color aColor = theLight->Color();
196 myDrawer->SetPointAspect (new Prs3d_PointAspect (myMarkerTypes[1], aColor, 3.0f));
197 myDisabledMarkerAspect = new Graphic3d_AspectMarker3d (Aspect_TOM_EMPTY, aColor, 3.0f);
198
199 Graphic3d_MaterialAspect aMat (Graphic3d_NameOfMaterial_UserDefined);
200 aMat.SetColor (aColor);
201 myDrawer->SetArrowAspect (new Prs3d_ArrowAspect());
202 myDrawer->ArrowAspect()->SetColor (aColor);
203 myDrawer->ArrowAspect()->Aspect()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
204 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial() = aMat;
205 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (Aspect_TOM_EMPTY);
206 myDrawer->ArrowAspect()->Aspect()->SetMarkerScale (2.0f);
207 myArrowLineAspectShadow = new Graphic3d_AspectLine3d (Quantity_NOC_BLACK, Aspect_TOL_SOLID,
208 theLight->Type() != Graphic3d_TypeOfLightSource_Ambient ? 3.0f : 1.0f);
209
210 myDrawer->SetupOwnShadingAspect();
211 myDrawer->ShadingAspect()->SetColor (aColor);
212 myDrawer->ShadingAspect()->SetMaterial (aMat);
213 myDrawer->ShadingAspect()->SetTransparency (0.5f);
214 myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TypeOfShadingModel_Unlit);
215
216 myDrawer->SetTextAspect (new Prs3d_TextAspect());
217 myDrawer->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_SHADOW);
218 myDrawer->TextAspect()->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK);
219 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_LEFT);
220 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOPFIRSTLINE);
221
222 updateLightTransformPersistence();
223
224 myDrawer->SetDisplayMode (0);
225 myDynHilightDrawer = new Prs3d_Drawer();
226 myDynHilightDrawer->Link (myDrawer);
227 myDynHilightDrawer->SetDisplayMode (1);
228 myDynHilightDrawer->SetColor (Quantity_NOC_CYAN1);
229
230 if (!myTransformPersistence.IsNull()
231 && myTransformPersistence->IsTrihedronOr2d())
232 {
233 myDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
234 myDynHilightDrawer->SetZLayer (Graphic3d_ZLayerId_Topmost);
235 myDrawer->TextAspect()->SetHorizontalJustification (Graphic3d_HTA_CENTER);
236 myDrawer->TextAspect()->SetVerticalJustification (Graphic3d_VTA_TOP);
237 }
238 }
239
240 //=======================================================================
241 //function : ProcessDragging
242 //purpose :
243 //=======================================================================
ProcessDragging(const Handle (AIS_InteractiveContext)& theCtx,const Handle (V3d_View)& theView,const Handle (SelectMgr_EntityOwner)& theOwner,const Graphic3d_Vec2i & theDragFrom,const Graphic3d_Vec2i & theDragTo,const AIS_DragAction theAction)244 Standard_Boolean AIS_LightSource::ProcessDragging (const Handle(AIS_InteractiveContext)& theCtx,
245 const Handle(V3d_View)& theView,
246 const Handle(SelectMgr_EntityOwner)& theOwner,
247 const Graphic3d_Vec2i& theDragFrom,
248 const Graphic3d_Vec2i& theDragTo,
249 const AIS_DragAction theAction)
250 {
251 if (Light()->Type() != Graphic3d_TypeOfLightSource_Directional)
252 {
253 return Standard_False;
254 }
255
256 switch (theAction)
257 {
258 case AIS_DragAction_Start:
259 {
260 myLocTrsfStart = LocalTransformation();
261 return Standard_True;
262 }
263 case AIS_DragAction_Update:
264 {
265 mySensSphere->ResetLastDetectedPoint();
266 SetLocalTransformation (myLocTrsfStart);
267 theCtx->MainSelector()->Pick (theDragFrom.x(), theDragFrom.y(), theView);
268 gp_Pnt aStartPosition = mySensSphere->LastDetectedPoint();
269
270 mySensSphere->ResetLastDetectedPoint();
271 theCtx->MainSelector()->Pick (theDragTo.x(), theDragTo.y(), theView);
272 gp_Pnt aCurrPosition = mySensSphere->LastDetectedPoint();
273 if (aCurrPosition.X() != RealLast()
274 && aStartPosition.Distance (aCurrPosition) > Precision::Confusion())
275 {
276 gp_Quaternion aQRot;
277 aQRot.SetRotation (gp_Vec (gp_Pnt (0, 0, 0), aStartPosition), gp_Vec (gp_Pnt (0, 0, 0), aCurrPosition));
278 gp_Trsf aTrsf;
279 aTrsf.SetRotation (aQRot);
280 SetLocalTransformation (myLocTrsfStart * aTrsf);
281 const Standard_Integer aHiMod = HasHilightMode() ? HilightMode() : 0;
282 theOwner->UpdateHighlightTrsf (theCtx->CurrentViewer(), theCtx->MainPrsMgr(), aHiMod);
283 }
284 return Standard_True;
285 }
286 case AIS_DragAction_Abort:
287 {
288 return Standard_True;
289 }
290 case AIS_DragAction_Stop:
291 {
292 GetHilightPresentation (theCtx->MainPrsMgr())->Clear();
293 break;
294 }
295 }
296 return Standard_False;
297 }
298
299 // =======================================================================
300 // function : updateLightAspects
301 // purpose :
302 // =======================================================================
updateLightAspects()303 void AIS_LightSource::updateLightAspects()
304 {
305 const Quantity_Color aBaseColor = myLightSource->Color();
306 const Quantity_Color aDimColor (aBaseColor.Rgb() * 0.3f);
307 const Quantity_Color aColor = myLightSource->IsEnabled() ? aBaseColor : aDimColor;
308 myDrawer->PointAspect()->SetColor (aColor);
309 myDrawer->PointAspect()->Aspect()->SetMarkerType (MarkerType (myLightSource->IsEnabled()));
310 myDrawer->PointAspect()->Aspect()->SetMarkerImage(MarkerImage(myLightSource->IsEnabled()));
311
312 myDisabledMarkerAspect->SetColor (aColor);
313 myDisabledMarkerAspect->SetMarkerScale(myDrawer->PointAspect()->Aspect()->MarkerScale());
314 myDisabledMarkerAspect->SetMarkerType (myLightSource->IsEnabled() ? Aspect_TOM_EMPTY : MarkerType (false));
315 myDisabledMarkerAspect->SetMarkerImage(MarkerImage (false));
316
317 myDrawer->ShadingAspect()->SetColor (aColor);
318 myDrawer->ArrowAspect() ->SetColor (aColor);
319 myDrawer->ArrowAspect()->Aspect()->ChangeFrontMaterial().SetColor (aColor);
320
321 if (myLightSource->Type() == Graphic3d_TypeOfLightSource_Directional)
322 {
323 const Standard_Real anAngleTol = 2.0 * M_PI / 180.0;
324 Aspect_TypeOfMarker aDirMark = Aspect_TOM_EMPTY;
325 if (myLightSource->IsEnabled()
326 && myLightSource->IsHeadlight()
327 && myLightSource->Direction().IsParallel (gp::DZ(), anAngleTol))
328 {
329 aDirMark = myLightSource->Direction().IsOpposite (-gp::DZ(), anAngleTol) ? myOpposMarkerType : myCodirMarkerType;
330 }
331 myDrawer->ArrowAspect()->Aspect()->SetMarkerType (aDirMark);
332 }
333 SynchronizeAspects();
334 }
335
336 // =======================================================================
337 // function : updateLightTransformPersistence
338 // purpose :
339 // =======================================================================
updateLightTransformPersistence()340 void AIS_LightSource::updateLightTransformPersistence()
341 {
342 Handle(Graphic3d_TransformPers) aTrsfPers = myTransformPersistence;
343 switch (myLightSource->Type())
344 {
345 case Graphic3d_TypeOfLightSource_Ambient:
346 {
347 if (!myIsZoomable)
348 {
349 if (aTrsfPers.IsNull() || !aTrsfPers->IsTrihedronOr2d())
350 {
351 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_TriedronPers, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
352 }
353 }
354 else
355 {
356 aTrsfPers.Nullify();
357 }
358 break;
359 }
360 case Graphic3d_TypeOfLightSource_Directional:
361 {
362 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_2d : Graphic3d_TMF_TriedronPers;
363 if (myIsZoomable)
364 {
365 aMode = myLightSource->IsHeadlight() ? Graphic3d_TMF_CameraPers : Graphic3d_TMF_None;
366 }
367 if (aMode != Graphic3d_TMF_None)
368 {
369 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
370 {
371 if (aMode == Graphic3d_TMF_CameraPers)
372 {
373 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
374 }
375 else
376 {
377 aTrsfPers = new Graphic3d_TransformPers (aMode, Aspect_TOTP_LEFT_UPPER, Graphic3d_Vec2i(50));
378 }
379 }
380 }
381 else
382 {
383 aTrsfPers.Nullify();
384 }
385 break;
386 }
387 case Graphic3d_TypeOfLightSource_Positional:
388 case Graphic3d_TypeOfLightSource_Spot:
389 {
390 Graphic3d_TransModeFlags aMode = myLightSource->IsHeadlight()
391 ? Graphic3d_TMF_CameraPers
392 : (!myIsZoomable ? Graphic3d_TMF_ZoomPers : Graphic3d_TMF_None);
393 if (aMode != Graphic3d_TMF_None)
394 {
395 if (aTrsfPers.IsNull() || aTrsfPers->Mode() != aMode)
396 {
397 if (aMode == Graphic3d_TMF_CameraPers)
398 {
399 aTrsfPers = new Graphic3d_TransformPers (Graphic3d_TMF_CameraPers);
400 }
401 else
402 {
403 aTrsfPers = new Graphic3d_TransformPers (aMode, myLightSource->Position());
404 }
405 }
406 if (aMode == Graphic3d_TMF_ZoomPers)
407 {
408 aTrsfPers->SetAnchorPoint (myLightSource->Position());
409 }
410 }
411 else
412 {
413 aTrsfPers.Nullify();
414 }
415 break;
416 }
417 }
418
419 SetTransformPersistence (aTrsfPers);
420 }
421
422 // =======================================================================
423 // function : updateLightLocalTransformation
424 // purpose :
425 // =======================================================================
updateLightLocalTransformation()426 void AIS_LightSource::updateLightLocalTransformation()
427 {
428 myLocalTransformation.Nullify();
429 switch (myLightSource->Type())
430 {
431 case Graphic3d_TypeOfLightSource_Ambient:
432 {
433 if (myIsZoomable)
434 {
435 gp_Trsf aTrsf;
436 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
437 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
438 }
439 break;
440 }
441 case Graphic3d_TypeOfLightSource_Directional:
442 {
443 const gp_Pnt aLightPos = (myIsZoomable && !myLightSource->IsHeadlight())
444 ? myLightSource->DisplayPosition()
445 : gp::Origin();
446 gp_Trsf aTrsf;
447 const gp_Ax2 anAx2 (aLightPos, -myLightSource->Direction());
448 aTrsf.SetTransformation (anAx2, gp_Ax3());
449 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
450 break;
451 }
452 case Graphic3d_TypeOfLightSource_Positional:
453 {
454 if (myIsZoomable)
455 {
456 gp_Trsf aTrsf;
457 aTrsf.SetTranslation (gp::Origin(), myLightSource->Position());
458 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
459 }
460 break;
461 }
462 case Graphic3d_TypeOfLightSource_Spot:
463 {
464 gp_Trsf aTrsf;
465 const gp_Ax2 anAx2 (myIsZoomable ? myLightSource->Position() : gp::Origin(), -myLightSource->Direction());
466 aTrsf.SetTransformation (anAx2, gp_Ax3());
467 myLocalTransformation = new TopLoc_Datum3D (aTrsf);
468 break;
469 }
470 }
471 UpdateTransformation();
472 }
473
474 // =======================================================================
475 // function : setLocalTransformation
476 // purpose :
477 // =======================================================================
setLocalTransformation(const Handle (TopLoc_Datum3D)& theTrsf)478 void AIS_LightSource::setLocalTransformation (const Handle(TopLoc_Datum3D)& theTrsf)
479 {
480 const gp_Trsf aTrsf = !theTrsf.IsNull() ? theTrsf->Transformation() : gp_Trsf();
481 switch (myLightSource->Type())
482 {
483 case Graphic3d_TypeOfLightSource_Ambient:
484 {
485 break;
486 }
487 case Graphic3d_TypeOfLightSource_Directional:
488 {
489 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
490 myLightSource->SetDirection (aNewDir);
491 if (myIsZoomable)
492 {
493 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
494 myLightSource->SetDisplayPosition (aNewPos);
495 }
496 break;
497 }
498 case Graphic3d_TypeOfLightSource_Positional:
499 {
500 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
501 myLightSource->SetPosition (aNewPos);
502 break;
503 }
504 case Graphic3d_TypeOfLightSource_Spot:
505 {
506 gp_Pnt aNewPos = gp::Origin().Transformed (aTrsf);
507 myLightSource->SetPosition (aNewPos);
508
509 gp_Dir aNewDir = (-gp::DZ()).Transformed (aTrsf);
510 myLightSource->SetDirection (aNewDir);
511 break;
512 }
513 }
514
515 base_type::setLocalTransformation (new TopLoc_Datum3D (aTrsf));
516
517 updateLightAspects();
518 updateLightTransformPersistence();
519 }
520
521 // =======================================================================
522 // function : Compute
523 // purpose :
524 // =======================================================================
Compute(const Handle (PrsMgr_PresentationManager)&,const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)525 void AIS_LightSource::Compute (const Handle(PrsMgr_PresentationManager)& ,
526 const Handle(Prs3d_Presentation)& thePrs,
527 const Standard_Integer theMode)
528 {
529 thePrs->SetInfiniteState (myInfiniteState);
530 if (theMode != 0
531 && theMode != 1)
532 {
533 return;
534 }
535
536 if (theMode == 0)
537 {
538 updateLightAspects();
539 updateLightTransformPersistence();
540 updateLightLocalTransformation();
541 }
542
543 switch (myLightSource->Type())
544 {
545 case Graphic3d_TypeOfLightSource_Ambient: computeAmbient (thePrs, theMode); break;
546 case Graphic3d_TypeOfLightSource_Directional: computeDirectional(thePrs, theMode); break;
547 case Graphic3d_TypeOfLightSource_Positional: computePositional (thePrs, theMode); break;
548 case Graphic3d_TypeOfLightSource_Spot: computeSpot (thePrs, theMode); break;
549 }
550
551 if (myToDisplayName)
552 {
553 TCollection_AsciiString aPrefix = !myTransformPersistence.IsNull()
554 && myTransformPersistence->IsTrihedronOr2d()
555 ? "\n" : " ";
556 TCollection_AsciiString aName = aPrefix + myLightSource->Name();
557 Prs3d_Text::Draw (thePrs->NewGroup(), myDrawer->TextAspect(), aName, gp::Origin());
558 }
559 }
560
561 // =======================================================================
562 // function : computeAmbient
563 // purpose :
564 // =======================================================================
computeAmbient(const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)565 void AIS_LightSource::computeAmbient (const Handle(Prs3d_Presentation)& thePrs,
566 const Standard_Integer theMode)
567 {
568 const gp_XYZ aLightPos = gp::Origin().XYZ();
569 if (theMode == 0)
570 {
571 Handle(Graphic3d_ArrayOfTriangles) aSphereArray = Prs3d_ToolSphere::Create (mySize * 0.25, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
572 Handle(Graphic3d_Group) aSphereGroup = thePrs->NewGroup();
573 aSphereGroup->SetClosed (true);
574 aSphereGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
575 aSphereGroup->AddPrimitiveArray (aSphereArray);
576 }
577 if (theMode == 0
578 || theMode == 1)
579 {
580 const Standard_Real aLen = mySize * 0.25;
581 const Standard_Integer aNbArrows = 6;
582 const gp_Dir aDirList[6] = { -gp::DX(), gp::DX(), -gp::DY(), gp::DY(), -gp::DZ(), gp::DZ() };
583
584 const Prs3d_ToolCylinder aCylTool (mySize * 0.1, 0.0, mySize * 0.2, myNbSplitsArrow, myNbSplitsArrow);
585 Handle(Graphic3d_ArrayOfTriangles) aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
586 aNbArrows * aCylTool.TrianglesNb() * 3,
587 Graphic3d_ArrayFlags_VertexNormal);
588 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
589 for (Standard_Integer anArrIter = 0; anArrIter < aNbArrows; ++anArrIter)
590 {
591 const gp_Dir& aDir = aDirList[anArrIter];
592 const gp_XYZ aPnt = aLightPos + aDir.XYZ() * aLen;
593 if (!aLineArray.IsNull())
594 {
595 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 0.5);
596 aLineArray->AddVertex (aPnt + aDir.XYZ() * aLen * 1.5);
597 }
598 if (!aTrisArray.IsNull())
599 {
600 const gp_Ax3 aSystem (aPnt + aDir.XYZ() * aLen, -aDir);
601 gp_Trsf aTrsfCone;
602 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
603 aCylTool.FillArray (aTrisArray, aTrsfCone);
604 }
605 }
606
607 if (!aLineArray.IsNull())
608 {
609 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
610 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
611 aDirGroupShadow->AddPrimitiveArray (aLineArray);
612 }
613 if (!aTrisArray.IsNull())
614 {
615 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
616 anArrowGroup->SetClosed (true);
617 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
618 anArrowGroup->AddPrimitiveArray (aTrisArray);
619 }
620 }
621
622 {
623 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
624 aPoints->AddVertex (aLightPos);
625 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
626 aGroup->SetGroupPrimitivesAspect (theMode == 1 ? myDrawer->PointAspect()->Aspect() : myDisabledMarkerAspect);
627 aGroup->AddPrimitiveArray (aPoints);
628 }
629 }
630
631 // =======================================================================
632 // function : computeDirectional
633 // purpose :
634 // =======================================================================
computeDirectional(const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)635 void AIS_LightSource::computeDirectional (const Handle(Prs3d_Presentation)& thePrs,
636 const Standard_Integer theMode)
637 {
638 const Standard_Real aDistance = mySize * 0.5;
639 const Standard_Real aStep = aDistance * 0.5;
640
641 // light source direction is set to local transformation
642 const gp_Dir aLightDir = -gp::DZ();
643 const gp_XYZ aLightPos = -aStep * aLightDir.XYZ();
644
645 Standard_Integer aNbArrows = 1;
646 if (myNbArrows >= 9) { aNbArrows = 9; }
647 else if (myNbArrows >= 5) { aNbArrows = 5; }
648 else if (myNbArrows >= 3) { aNbArrows = 3; }
649 TColgp_Array1OfPnt aPoints (1, aNbArrows);
650 {
651 const gp_Ax2 anAxes (gp::Origin(), aLightDir);
652 const gp_XYZ aDY = anAxes.YDirection().XYZ() * aStep;
653 const gp_XYZ aDX = anAxes.XDirection().XYZ() * aStep;
654 const gp_XYZ aDXY = aDX + aDY;
655 switch (aNbArrows)
656 {
657 case 9:
658 {
659 aPoints.SetValue (6, aLightPos + aDY);
660 aPoints.SetValue (7, aLightPos + aDX);
661 aPoints.SetValue (8, aLightPos - aDY);
662 aPoints.SetValue (9, aLightPos - aDX);
663 }
664 Standard_FALLTHROUGH
665 case 5:
666 {
667 aPoints.SetValue (4, aLightPos - aDY + aDX);
668 aPoints.SetValue (5, aLightPos + aDY - aDX);
669 }
670 Standard_FALLTHROUGH
671 case 3:
672 {
673 aPoints.SetValue (2, aLightPos + aDXY);
674 aPoints.SetValue (3, aLightPos - aDXY);
675 }
676 Standard_FALLTHROUGH
677 case 1:
678 {
679 aPoints.SetValue (1, aLightPos);
680 break;
681 }
682 }
683 }
684
685 const Prs3d_ToolCylinder aCylTool (aDistance * 0.1, 0.0, aDistance * 0.2, myNbSplitsArrow, myNbSplitsArrow);
686 Handle(Graphic3d_ArrayOfTriangles) aTrisArray;
687 if (theMode == 0)
688 {
689 aTrisArray = new Graphic3d_ArrayOfTriangles (aNbArrows * aCylTool.VerticesNb(),
690 aNbArrows * aCylTool.TrianglesNb() * 3,
691 Graphic3d_ArrayFlags_VertexNormal);
692 }
693 Handle(Graphic3d_ArrayOfPoints) aPntArray = new Graphic3d_ArrayOfPoints (aNbArrows);
694 Handle(Graphic3d_ArrayOfSegments) aLineArray = new Graphic3d_ArrayOfSegments (aNbArrows * 2);
695 for (Standard_Integer aPntIter = aPoints.Lower(); aPntIter <= aPoints.Upper(); ++aPntIter)
696 {
697 const gp_Pnt aPnt = aPoints.Value (aPntIter);
698 if (!aPntArray.IsNull())
699 {
700 aPntArray->AddVertex (aPnt);
701 }
702 if (!aLineArray.IsNull())
703 {
704 aLineArray->AddVertex (aPnt);
705 aLineArray->AddVertex (gp_Pnt (aPnt.XYZ() + aLightDir.XYZ() * aDistance));
706 }
707 if (!aTrisArray.IsNull())
708 {
709 const gp_Ax3 aSystem (aPnt.XYZ() + aLightDir.XYZ() * aDistance, aLightDir);
710 gp_Trsf aTrsfCone;
711 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
712 aCylTool.FillArray (aTrisArray, aTrsfCone);
713 }
714 }
715
716 if (!aLineArray.IsNull() && theMode == 0)
717 {
718 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
719 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
720 aDirGroupShadow->AddPrimitiveArray (aLineArray);
721 }
722 if (!aLineArray.IsNull())
723 {
724 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
725 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
726 aDirGroup->AddPrimitiveArray (aLineArray);
727 }
728 if (!aTrisArray.IsNull())
729 {
730 Handle(Graphic3d_Group) anArrowGroup = thePrs->NewGroup();
731 anArrowGroup->SetClosed (true);
732 anArrowGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
733 anArrowGroup->AddPrimitiveArray (aTrisArray);
734 }
735 if (!aPntArray.IsNull())
736 {
737 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
738 aGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
739 aGroup->AddPrimitiveArray (aPntArray);
740 }
741 {
742 Handle(Graphic3d_ArrayOfPoints) aPntArray2 = new Graphic3d_ArrayOfPoints (1);
743 aPntArray2->AddVertex (aLightPos);
744 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
745 aGroup->SetGroupPrimitivesAspect (myDisabledMarkerAspect);
746 aGroup->AddPrimitiveArray (aPntArray2);
747 }
748 }
749
750 // =======================================================================
751 // function : computePositional
752 // purpose :
753 // =======================================================================
computePositional(const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)754 void AIS_LightSource::computePositional (const Handle(Prs3d_Presentation)& thePrs,
755 const Standard_Integer theMode)
756 {
757 // light source position is set to local transformation
758 const gp_XYZ aLightPos = gp::Origin().XYZ();
759 const Standard_Real aRadius = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : 0.0;
760 if (theMode == 0
761 && aRadius > 0.0
762 && myToDisplayRange)
763 {
764 Handle(Graphic3d_ArrayOfTriangles) aPosRangeArray = Prs3d_ToolSphere::Create (aRadius, myNbSplitsQuadric, myNbSplitsQuadric, gp_Trsf());
765 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
766 aRangeGroup->SetClosed (true);
767 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
768 aRangeGroup->AddPrimitiveArray (aPosRangeArray);
769 }
770 {
771 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
772 aPoints->AddVertex (aLightPos);
773 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
774 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
775 aGroup->AddPrimitiveArray (aPoints);
776 }
777 }
778
779 // =======================================================================
780 // function : computeSpot
781 // purpose :
782 // =======================================================================
computeSpot(const Handle (Prs3d_Presentation)& thePrs,const Standard_Integer theMode)783 void AIS_LightSource::computeSpot (const Handle(Prs3d_Presentation)& thePrs,
784 const Standard_Integer theMode)
785 {
786 // light source position and direction are set to local transformation
787 const gp_Dir aLightDir = -gp::DZ();
788 const gp_XYZ aLightPos = gp::Origin().XYZ();
789 const Standard_Real aDistance = (myIsZoomable && myLightSource->HasRange()) ? myLightSource->Range() : mySize;
790 {
791 Handle(Graphic3d_ArrayOfPoints) aPoints = new Graphic3d_ArrayOfPoints (1);
792 aPoints->AddVertex (aLightPos);
793
794 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
795 aGroup->SetGroupPrimitivesAspect (myDrawer->PointAspect()->Aspect());
796 aGroup->AddPrimitiveArray (aPoints);
797 }
798
799 {
800 Handle(Graphic3d_ArrayOfSegments) aDirArray = new Graphic3d_ArrayOfSegments (2);
801 aDirArray->AddVertex (aLightPos);
802 aDirArray->AddVertex (gp_Pnt (aLightPos + aLightDir.XYZ() * aDistance));
803
804 Handle(Graphic3d_Group) aDirGroupShadow = thePrs->NewGroup();
805 aDirGroupShadow->SetClosed (true);
806 aDirGroupShadow->SetGroupPrimitivesAspect (myArrowLineAspectShadow);
807 aDirGroupShadow->AddPrimitiveArray (aDirArray);
808
809 Handle(Graphic3d_Group) aDirGroup = thePrs->NewGroup();
810 aDirGroup->SetClosed (true);
811 aDirGroup->SetGroupPrimitivesAspect (myDrawer->ArrowAspect()->Aspect());
812 aDirGroup->AddPrimitiveArray (aDirArray);
813 }
814
815 if (theMode == 0
816 && myToDisplayRange)
817 {
818 const Standard_ShortReal aHalfAngle = myLightSource->Angle() / 2.0f;
819 const Standard_Real aRadius = aDistance * Tan (aHalfAngle);
820 gp_Ax3 aSystem (aLightPos + aLightDir.XYZ() * aDistance, -aLightDir);
821 gp_Trsf aTrsfCone;
822 aTrsfCone.SetTransformation (aSystem, gp_Ax3());
823 Handle(Graphic3d_ArrayOfTriangles) aSpotRangeArray = Prs3d_ToolCylinder::Create (aRadius, 0.0, aDistance,
824 myNbSplitsQuadric, myNbSplitsQuadric, aTrsfCone);
825
826 Handle(Graphic3d_Group) aRangeGroup = thePrs->NewGroup();
827 aRangeGroup->SetClosed (true);
828 aRangeGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
829 aRangeGroup->AddPrimitiveArray (aSpotRangeArray);
830 }
831 }
832
833 // =======================================================================
834 // function : ComputeSelection
835 // purpose :
836 // =======================================================================
ComputeSelection(const Handle (SelectMgr_Selection)& theSel,const Standard_Integer theMode)837 void AIS_LightSource::ComputeSelection (const Handle(SelectMgr_Selection)& theSel,
838 const Standard_Integer theMode)
839 {
840 if (theMode != 0)
841 {
842 return;
843 }
844
845 Handle(AIS_LightSourceOwner) anEntityOwner = new AIS_LightSourceOwner (this, 15);
846 {
847 if (myLightSource->Type() == Graphic3d_TypeOfLightSource_Directional)
848 {
849 mySensSphere = new Select3D_SensitiveSphere (anEntityOwner, gp::Origin(), mySize * 0.5);
850 theSel->Add (mySensSphere);
851 }
852
853 Handle(Select3D_SensitivePoint) aSensPosition = new Select3D_SensitivePoint (anEntityOwner, gp::Origin());
854 aSensPosition->SetSensitivityFactor (12);
855 if (!myTransformPersistence.IsNull()
856 && myTransformPersistence->IsTrihedronOr2d())
857 {
858 aSensPosition->SetSensitivityFactor (Max (12, Standard_Integer (mySize * 0.5)));
859 }
860 theSel->Add (aSensPosition);
861 }
862 }
863