0029290: Visualization, TKOpenGl - allow defining Light source per ZLayer
authorkgv <kgv@opencascade.com>
Thu, 2 Nov 2017 12:36:20 +0000 (15:36 +0300)
committerkgv <kgv@opencascade.com>
Thu, 30 Nov 2017 20:09:23 +0000 (23:09 +0300)
Graphic3d_CLight is now defined as a class inheriting Standard_Transient,
so that it's fields now should be accessed through methods.
Graphic3d_CLight::IsEnabled() - new property allowing to disable light source everywhere.
Confusing alias OpenGl_Light has been removed.

Graphic3d_CLight::SetAttenuation() - the upper limit 1.0 of attenuation factors has been removed
since it contradicts to OpenGL specs and does not make sense.

Graphic3d_ZLayerSettings::Lights() - light sources list is now property of ZLayer.
When defined, it overrides light sources defined for View/Viewer.
New class Graphic3d_LightSet has been defined to define a set of light sources.

V3d_Light - removed obsolete interface for debug drawing lights sources.
V3d_Light is now an alias to Graphic3d_CLight.
V3d_TypeOfLight is now defined as a typedef to Graphic3d_TypeOfLightSource.

61 files changed:
dox/dev_guides/upgrade/upgrade.md
samples/mfc/occtdemo/Textures/Textures_Presentation.cpp
samples/mfc/occtdemo/TexturesExt/TexturesExt_Presentation.cpp
samples/mfc/standard/04_Viewer3d/src/TexturesExt_Presentation.cpp
samples/mfc/standard/04_Viewer3d/src/Viewer3dView.cpp
samples/tcl/materials.tcl
src/Graphic3d/FILES
src/Graphic3d/Graphic3d_CLight.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_CLight.hxx
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_LightSet.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_LightSet.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_TypeOfLightSource.hxx
src/Graphic3d/Graphic3d_TypeOfShadingModel.hxx
src/Graphic3d/Graphic3d_ZLayerSettings.hxx
src/OpenGl/FILES
src/OpenGl/OpenGl_Layer.cxx
src/OpenGl/OpenGl_LayerList.cxx
src/OpenGl/OpenGl_Light.hxx [deleted file]
src/OpenGl/OpenGl_SceneGeometry.cxx
src/OpenGl/OpenGl_ShaderManager.cxx
src/OpenGl/OpenGl_ShaderManager.hxx
src/OpenGl/OpenGl_ShaderStates.cxx
src/OpenGl/OpenGl_ShaderStates.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Raytrace.cxx
src/OpenGl/OpenGl_View_Redraw.cxx
src/StdPrs/StdPrs_Plane.cxx
src/V3d/FILES
src/V3d/V3d.cxx
src/V3d/V3d.hxx
src/V3d/V3d_AmbientLight.cxx
src/V3d/V3d_AmbientLight.hxx
src/V3d/V3d_DirectionalLight.cxx
src/V3d/V3d_DirectionalLight.hxx
src/V3d/V3d_Light.cxx [deleted file]
src/V3d/V3d_Light.hxx
src/V3d/V3d_ListOfLight.hxx
src/V3d/V3d_PositionLight.cxx
src/V3d/V3d_PositionLight.hxx
src/V3d/V3d_PositionalLight.cxx
src/V3d/V3d_PositionalLight.hxx
src/V3d/V3d_SpotLight.cxx
src/V3d/V3d_SpotLight.hxx
src/V3d/V3d_TypeOfLight.hxx
src/V3d/V3d_View.cxx
src/V3d/V3d_View.hxx
src/V3d/V3d_Viewer.cxx
src/V3d/V3d_Viewer.hxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
tests/v3d/glsl/phong_pos1
tests/v3d/glsl/phong_pos3 [new file with mode: 0644]
tests/v3d/glsl/phong_pos4 [new file with mode: 0644]
tests/v3d/materials/bug24855
tests/v3d/raytrace/bug24130
tests/v3d/raytrace/bug24819
tests/v3d/raytrace/bug25201
tests/v3d/raytrace/bug26617
tests/v3d/raytrace/refraction
tests/v3d/raytrace/textures

index 1909ee2..7a3d447 100644 (file)
@@ -1501,4 +1501,22 @@ The following obsolete features have been removed:
   - *IntTools_IndexedDataMapOfTransientAddress* is removed as unused;
 * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
 * The class *BOPTools* has been removed as duplicate of the class *TopExp*;
-* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.
\ No newline at end of file
+* The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.
+
+@section upgrade_occt730 Upgrade to OCCT 7.3.0
+
+@subsection upgrade_730_lights Light sources
+
+Multiple changes have been applied to lights management within TKV3d and TKOpenGl:
+* V3d_Light class is now an alias to Graphic3d_CLight.
+  Graphic3d_CLight is now a Handle class with refactored methods for managing light source parameters
+  (preserving most methods of V3d_Light sub-classes to simplify porting).
+* Obsolete debugging functionality for drawing lights source has been removed from V3d_Light.
+  Methods and constructors taking parameters for this drawing and not affecting light definition itself has been also removed.
+* Light constructors taking V3d_Viewer has been marked deprecated.
+  Application may call V3d_Viewer::AddLight() explicitly to register new light sources created by new constructors within V3d_Viewer, but this step is now optional.
+* The upper limit of 8 light sources has been removed.
+* Dedicated classes per light source type V3d_AmbientLight, V3d_DirectionalLight, V3d_PositionalLight and V3d_SpotLight have been preserved,
+  but it is now possible defining light of any type by creating base class Graphic3d_CLight directly.
+  Dedicated classes only hides visibility of unrelated light properties depending on its type.
+* Calling V3d_Viewer::UpdateLights() is no more required after modifying light sources properties (color, position, etc.).
index cf5b1e6..68e4497 100755 (executable)
@@ -137,12 +137,12 @@ void Textures_Presentation::Init()
 //================================================================
 void Textures_Presentation::lightsOnOff(Standard_Boolean isOn)
 {
-  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg);
-  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos);
-  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos);
-  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg);
-  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos);
-  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos);
+  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg);
+  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos);
+  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos);
+  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg);
+  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos);
+  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos);
 
   if (isOn)
   {
index 1a548b5..07ac0bb 100755 (executable)
@@ -185,12 +185,12 @@ Standard_Boolean TexturesExt_Presentation::loadShape(TopoDS_Shape& aShape,
 //================================================================
 void TexturesExt_Presentation::lightsOnOff(Standard_Boolean isOn)
 {
-  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg);
-  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos);
-  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos);
-  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg);
-  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos);
-  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos);
+  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg);
+  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos);
+  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos);
+  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg);
+  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos);
+  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos);
 
   if (isOn)
   {
index 902a504..b542673 100755 (executable)
@@ -191,12 +191,12 @@ Standard_Boolean TexturesExt_Presentation::loadShape(TopoDS_Shape& aShape,
 //================================================================
 void TexturesExt_Presentation::lightsOnOff(Standard_Boolean isOn)
 {
-  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZneg);
-  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZpos);
-  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(getViewer(), V3d_XposYnegZpos);
-  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(getViewer(), V3d_XnegYnegZneg);
-  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(getViewer(), V3d_XnegYposZpos);
-  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(getViewer(), V3d_XposYposZpos);
+  static Handle(V3d_Light) aLight1 = new V3d_DirectionalLight(V3d_XnegYposZneg);
+  static Handle(V3d_Light) aLight2 = new V3d_DirectionalLight(V3d_XnegYnegZpos);
+  static Handle(V3d_Light) aLight3 = new V3d_DirectionalLight(V3d_XposYnegZpos);
+  static Handle(V3d_Light) aLight4 = new V3d_DirectionalLight(V3d_XnegYnegZneg);
+  static Handle(V3d_Light) aLight5 = new V3d_DirectionalLight(V3d_XnegYposZpos);
+  static Handle(V3d_Light) aLight6 = new V3d_DirectionalLight(V3d_XposYposZpos);
 
   if (isOn)
   {
index 9be1e1a..01da072 100755 (executable)
@@ -416,7 +416,7 @@ GetDocument()->UpdateResultMessageDlg("SetPosition",Message);
         case  CurAction3d_BeginSpotLight :
                        {
                        p1 = ConvertClickToPoint(point.x,point.y,myView);
-                       myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(),0.,0.,1., p1.X(),p1.Y(),p1.Z(),Quantity_NOC_RED);
+                       myCurrent_SpotLight = new V3d_SpotLight (p1, gp_Dir (gp_XYZ (0.0, 0.0, 1.0) - p1.XYZ()), Quantity_NOC_RED);
                        myView->SetLightOn(myCurrent_SpotLight);
                        NbActiveLights++;
                        p2 = gp_Pnt(p1.X(),p1.Y(),p1.Z()+1.);
@@ -461,7 +461,7 @@ GetDocument()->UpdateResultMessageDlg("SetAngle",Message);
                                directionalEdgeShape->Set(MakeEdge.Edge());
                                GetDocument()->GetAISContext()->Display (directionalEdgeShape, 0, -1, Standard_True);
                        // Create a directional light
-                               myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), p1.X(),p1.Y(),p1.Z(),0.,0.,1.);
+                               myCurrent_DirectionalLight = new V3d_DirectionalLight (gp_Dir (p1.XYZ() - gp_XYZ (0.,0.,1.)));
                                myView->SetLightOn(myCurrent_DirectionalLight);
                                NbActiveLights++;
                                ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the target point");
@@ -745,7 +745,7 @@ void CViewer3dView::OnMouseMove(UINT nFlags, CPoint point)
                                        0, p2.Distance(p3), coneHeigth);
                                spotConeShape->Set(MakeCone.Solid());
                                GetDocument()->GetAISContext()->Redisplay(spotConeShape,0,Standard_True);
-                               myCurrent_SpotLight->SetAngle(atan(p2.Distance(p3)/p1.Distance(p2))) ;
+                               myCurrent_SpotLight->SetAngle((float )atan(p2.Distance(p3)/p1.Distance(p2))) ;
                                myView->UpdateLights();
                        }
                }
@@ -894,7 +894,7 @@ void CViewer3dView::OnDirectionalLight()
        myCurrentMode = CurAction3d_BeginDirectionalLight;
 
 TCollection_AsciiString Message("\
-myCurrent_DirectionalLight = new V3d_DirectionalLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp);\n\
+myCurrent_DirectionalLight = new V3d_DirectionalLight (gp_Dir (theDirection));\n\
 \n\
 myView->SetLightOn(myCurrent_DirectionalLight);\n\
 \n\
@@ -920,7 +920,7 @@ void CViewer3dView::OnSpotLight()
        myCurrentMode = CurAction3d_BeginSpotLight;
 
 TCollection_AsciiString Message("\
-myCurrent_SpotLight = new V3d_SpotLight(myView->Viewer(), Xt, Yt, Zt, Xp, Yp, Zp,Quantity_NOC_RED);\n\
+myCurrent_SpotLight = new V3d_SpotLight (gp_Pnt (thePosition), gp_Dir (theDirection), Quantity_NOC_RED);\n\
 \n\
 myView->SetLightOn(myCurrent_SpotLight);\n\
 \n\
@@ -942,14 +942,16 @@ void CViewer3dView::OnPositionalLight()
                return;
        }
 
-       myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),0,0,0,Quantity_NOC_GREEN,1,0);
+       myCurrent_PositionalLight=new V3d_PositionalLight (gp_Pnt (0,0,0), Quantity_NOC_GREEN);
+    myCurrent_PositionalLight->SetAttenuation (1, 0);
        myView->SetLightOn(myCurrent_PositionalLight);
        NbActiveLights++;
        ((OCC_MainFrame*)AfxGetMainWnd())->SetStatusMessage("Pick the light position");
        myCurrentMode = CurAction3d_BeginPositionalLight;
 
 TCollection_AsciiString Message("\
-myCurrent_PositionalLight=new V3d_PositionalLight(myView->Viewer(),Xp, Yp, Zp,Quantity_NOC_GREEN,1,0);\n\
+myCurrent_PositionalLight=new V3d_PositionalLight (gp_Pnt(thePosition),Quantity_NOC_GREEN);\n\
+myCurrent_PositionalLight->SetAttenuation (1, 0);\n\
 \n\
 myView->SetLightOn(myCurrent_PositionalLight) ;\n\
   ");
@@ -971,14 +973,14 @@ void CViewer3dView::OnAmbientLight()
                return;
        }
 
-       myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);
+       myCurrent_AmbientLight=new V3d_AmbientLight (Quantity_NOC_GRAY);
        myView->SetLightOn(myCurrent_AmbientLight) ;    
        NbActiveLights++;
 
        myView->UpdateLights();
 
 TCollection_AsciiString Message("\
-myCurrent_AmbientLight=new V3d_AmbientLight(myView->Viewer(), Quantity_NOC_GRAY);\n\
+myCurrent_AmbientLight=new V3d_AmbientLight(Quantity_NOC_GRAY);\n\
 \n\
 myView->SetLightOn(myCurrent_AmbientLight) ;\n\
   ");
index ba40779..cfef461 100644 (file)
@@ -70,7 +70,8 @@ vclear
 vtop
 vglinfo
 vsetgradientbg 180 200 255 180 180 180 2
-vlight change 0 pos -1 1 1
+
+vlight -change 0 -dir 0.577 -0.577 -0.577
 vsetdispmode 1
 vrenderparams -msaa 8
 
index 42151dd..3f7ab9f 100755 (executable)
@@ -30,6 +30,7 @@ Graphic3d_Camera.cxx
 Graphic3d_Camera.hxx
 Graphic3d_CameraTile.hxx
 Graphic3d_CappingFlags.hxx
+Graphic3d_CLight.cxx
 Graphic3d_CLight.hxx
 Graphic3d_ClipPlane.cxx
 Graphic3d_ClipPlane.hxx
@@ -58,6 +59,8 @@ Graphic3d_HorizontalTextAlignment.hxx
 Graphic3d_IndexBuffer.hxx
 Graphic3d_IndexedMapOfAddress.hxx
 Graphic3d_LevelOfTextureAnisotropy.hxx
+Graphic3d_LightSet.cxx
+Graphic3d_LightSet.hxx
 Graphic3d_MapIteratorOfMapOfStructure.hxx
 Graphic3d_MapOfObject.hxx
 Graphic3d_MapOfStructure.hxx
diff --git a/src/Graphic3d/Graphic3d_CLight.cxx b/src/Graphic3d/Graphic3d_CLight.cxx
new file mode 100644 (file)
index 0000000..0443787
--- /dev/null
@@ -0,0 +1,235 @@
+// Copyright (c) 2017 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 <Graphic3d_CLight.hxx>
+
+#include <Standard_Atomic.hxx>
+#include <Standard_OutOfRange.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient)
+
+namespace
+{
+  static volatile Standard_Integer THE_LIGHT_COUNTER = 0;
+}
+
+// =======================================================================
+// function : makeId
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::makeId()
+{
+  TCollection_AsciiString aTypeSuffix;
+  switch (myType)
+  {
+    case Graphic3d_TOLS_AMBIENT:     aTypeSuffix = "amb"; break;
+    case Graphic3d_TOLS_DIRECTIONAL: aTypeSuffix = "dir"; break;
+    case Graphic3d_TOLS_POSITIONAL:  aTypeSuffix = "pos"; break;
+    case Graphic3d_TOLS_SPOT:        aTypeSuffix = "spot"; break;
+  }
+
+  myId = TCollection_AsciiString ("Graphic3d_CLight_") + aTypeSuffix
+       + TCollection_AsciiString (Standard_Atomic_Increment (&THE_LIGHT_COUNTER));
+}
+
+// =======================================================================
+// function : Graphic3d_CLight
+// purpose  :
+// =======================================================================
+Graphic3d_CLight::Graphic3d_CLight (Graphic3d_TypeOfLightSource theType)
+: myPosition   (0.0,  0.0,  0.0),
+  myColor      (1.0f, 1.0f, 1.0f, 1.0f),
+  myDirection  (0.0f, 0.0f, 0.0f, 0.0f),
+  myParams     (0.0f, 0.0f, 0.0f, 0.0f),
+  mySmoothness (0.0f),
+  myIntensity  (1.0f),
+  myType       (theType),
+  myRevision   (0),
+  myIsHeadlight(false),
+  myIsEnabled  (true)
+{
+  switch (theType)
+  {
+    case Graphic3d_TOLS_AMBIENT:
+    {
+      break;
+    }
+    case Graphic3d_TOLS_DIRECTIONAL:
+    {
+      mySmoothness = 0.2f;
+      myIntensity  = 20.0f;
+      break;
+    }
+    case Graphic3d_TOLS_POSITIONAL:
+    {
+      changeConstAttenuation()  = 1.0f;
+      changeLinearAttenuation() = 0.0f;
+      break;
+    }
+    case Graphic3d_TOLS_SPOT:
+    {
+      changeConstAttenuation()  = 1.0f;
+      changeLinearAttenuation() = 0.0f;
+      changeConcentration()     = 1.0f;
+      changeAngle()             = 0.523599f;
+      break;
+    }
+  }
+  makeId();
+}
+
+// =======================================================================
+// function : SetColor
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetColor (const Quantity_Color& theColor)
+{
+  updateRevisionIf (myColor.GetRGB().IsDifferent (theColor));
+  myColor.SetRGB (theColor);
+}
+
+// =======================================================================
+// function : SetEnabled
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetEnabled (Standard_Boolean theIsOn)
+{
+  updateRevisionIf (myIsEnabled != theIsOn);
+  myIsEnabled = theIsOn;
+}
+
+// =======================================================================
+// function : SetHeadlight
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetHeadlight (Standard_Boolean theValue)
+{
+  updateRevisionIf (myIsHeadlight != theValue);
+  myIsHeadlight = theValue;
+}
+
+// =======================================================================
+// function : SetDirection
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetDirection (const gp_Dir& theDir)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT
+                               && myType != Graphic3d_TOLS_DIRECTIONAL,
+                                  "Graphic3d_CLight::SetDirection(), incorrect light type");
+  updateRevisionIf (Abs (myDirection.x() - static_cast<Standard_ShortReal> (theDir.X())) > ShortRealEpsilon()
+                 || Abs (myDirection.y() - static_cast<Standard_ShortReal> (theDir.Y())) > ShortRealEpsilon()
+                 || Abs (myDirection.z() - static_cast<Standard_ShortReal> (theDir.Z())) > ShortRealEpsilon());
+
+  myDirection.x() = static_cast<Standard_ShortReal> (theDir.X());
+  myDirection.y() = static_cast<Standard_ShortReal> (theDir.Y());
+  myDirection.z() = static_cast<Standard_ShortReal> (theDir.Z());
+}
+
+// =======================================================================
+// function : SetPosition
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetPosition (const gp_Pnt& thePosition)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT
+                               && myType != Graphic3d_TOLS_POSITIONAL,
+                                  "Graphic3d_CLight::SetDirection(), incorrect light type");
+  updateRevisionIf (!myPosition.IsEqual (thePosition, gp::Resolution()));
+  myPosition = thePosition;
+}
+
+// =======================================================================
+// function : SetIntensity
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetIntensity (Standard_ShortReal theValue)
+{
+  Standard_OutOfRange_Raise_if (theValue <= 0.0f, "Graphic3d_CLight::SetIntensity(), Negative value for intensity");
+  updateRevisionIf (Abs (myIntensity - theValue) > ShortRealEpsilon());
+  myIntensity = theValue;
+}
+
+// =======================================================================
+// function : SetAngle
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetAngle (Standard_ShortReal theAngle)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT,
+                                  "Graphic3d_CLight::SetAngle(), incorrect light type");
+  Standard_OutOfRange_Raise_if (theAngle <= 0.0 || theAngle >= M_PI,
+                                "Graphic3d_CLight::SetAngle(), bad angle");
+  updateRevisionIf (Abs (changeAngle() - theAngle) > ShortRealEpsilon());
+  changeAngle() = theAngle;
+}
+
+// =======================================================================
+// function : SetAttenuation
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetAttenuation (Standard_ShortReal theConstAttenuation,
+                                       Standard_ShortReal theLinearAttenuation)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_POSITIONAL
+                               && myType != Graphic3d_TOLS_SPOT,
+                                  "Graphic3d_CLight::SetAttenuation(), incorrect light type");
+  Standard_OutOfRange_Raise_if (theConstAttenuation  < 0.0f
+                             || theLinearAttenuation < 0.0f
+                             || theConstAttenuation + theLinearAttenuation == 0.0f, "Graphic3d_CLight::SetAttenuation(), bad coefficient");
+  updateRevisionIf (Abs (changeConstAttenuation()  - theConstAttenuation)  > ShortRealEpsilon()
+                 || Abs (changeLinearAttenuation() - theLinearAttenuation) > ShortRealEpsilon());
+  changeConstAttenuation()  = theConstAttenuation;
+  changeLinearAttenuation() = theLinearAttenuation;
+}
+
+// =======================================================================
+// function : SetConcentration
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetConcentration (Standard_ShortReal theConcentration)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_SPOT, "Graphic3d_CLight::SetConcentration(), incorrect light type");
+  Standard_OutOfRange_Raise_if (theConcentration < 0.0f || theConcentration > 1.0f,
+                                "Graphic3d_CLight::SetConcentration(), bad coefficient");
+  updateRevisionIf (Abs (changeConcentration() - theConcentration) > ShortRealEpsilon());
+  changeConcentration() = theConcentration;
+}
+
+// =======================================================================
+// function : SetSmoothRadius
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetSmoothRadius (Standard_ShortReal theValue)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_POSITIONAL
+                               && myType != Graphic3d_TOLS_SPOT,
+                                  "Graphic3d_CLight::SetSmoothRadius(), incorrect light type");
+  Standard_OutOfRange_Raise_if (theValue < 0.0f, "Graphic3d_CLight::SetSmoothRadius(), Bad value for smoothing radius");
+  updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon());
+  mySmoothness = theValue;
+}
+
+// =======================================================================
+// function : SetSmoothAngle
+// purpose  :
+// =======================================================================
+void Graphic3d_CLight::SetSmoothAngle (Standard_ShortReal theValue)
+{
+  Standard_ProgramError_Raise_if (myType != Graphic3d_TOLS_DIRECTIONAL,
+                                  "Graphic3d_CLight::SetSmoothAngle(), incorrect light type");
+  Standard_OutOfRange_Raise_if (theValue < 0.0f || theValue > Standard_ShortReal(M_PI / 2.0),
+                                "Graphic3d_CLight::SetSmoothAngle(), Bad value for smoothing angle");
+  updateRevisionIf (Abs (mySmoothness - theValue) > ShortRealEpsilon());
+  mySmoothness = theValue;
+}
index 8a2283c..fd8b68c 100644 (file)
 #ifndef _Graphic3d_CLight_HeaderFile
 #define _Graphic3d_CLight_HeaderFile
 
+#include <gp_Dir.hxx>
 #include <Graphic3d_TypeOfLightSource.hxx>
 #include <Graphic3d_Vec.hxx>
 #include <NCollection_List.hxx>
-
-//! Light definition
-struct Graphic3d_CLight
+#include <TCollection_AsciiString.hxx>
+#include <Quantity_ColorRGBA.hxx>
+
+//! Generic light source definition.
+//! This class defines arbitrary light source - see Graphic3d_TypeOfLightSource enumeration.
+//! Some parameters are applicable only to particular light type;
+//! calling methods unrelated to current type will throw an exception.
+class Graphic3d_CLight : public Standard_Transient
 {
-
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_CLight, Standard_Transient)
 public:
 
-  Graphic3d_Vec3d             Position;    //!< light position
-  Graphic3d_Vec4              Color;       //!< light color
-  Graphic3d_Vec4              Direction;   //!< direction of directional/spot light
-  Graphic3d_Vec4              Params;      //!< packed light parameters
-  Standard_ShortReal          Smoothness;  //!< radius (cone angle) for point (directional) light
-  Standard_ShortReal          Intensity;   //!< intensity multiplier for light
-  Graphic3d_TypeOfLightSource Type;        //!< Graphic3d_TypeOfLightSource enumeration
-  Standard_Boolean            IsHeadlight; //!< flag to mark head light
+  //! Empty constructor, which should be followed by light source properties configuration.
+  Standard_EXPORT Graphic3d_CLight (Graphic3d_TypeOfLightSource theType);
+
+  //! Returns the Type of the Light, cannot be changed after object construction.
+  Graphic3d_TypeOfLightSource Type() const { return myType; }
+
+  //! Returns light source name; empty string by default.
+  const TCollection_AsciiString& Name() const { return myName; }
+
+  //! Sets light source name.
+  void SetName (const TCollection_AsciiString& theName) { myName = theName; }
+
+  //! Returns the color of the light source; WHITE by default.
+  const Quantity_Color& Color() const { return myColor.GetRGB(); }
+
+  //! Defines the color of a light source by giving the basic color.
+  Standard_EXPORT void SetColor (const Quantity_Color& theColor);
 
-  //! Const attenuation factor of positional light source
-  Standard_ShortReal  ConstAttenuation()  const { return Params.x();  }
+  //! Check that the light source is turned on; TRUE by default.
+  //! This flag affects all occurrences of light sources, where it was registered and activated;
+  //! so that it is possible defining an active light in View which is actually in disabled state.
+  Standard_Boolean IsEnabled() const { return myIsEnabled; }
+
+  //! Change enabled state of the light state.
+  //! This call does not remove or deactivate light source in Views/Viewers;
+  //! instead it turns it OFF so that it just have no effect.
+  Standard_EXPORT void SetEnabled (Standard_Boolean theIsOn);
+
+  //! Returns true if the light is a headlight; FALSE by default.
+  //! Headlight flag means that light position/direction are defined not in a World coordinate system, but relative to the camera orientation.
+  Standard_Boolean IsHeadlight() const { return myIsHeadlight; }
+
+  //! Alias for IsHeadlight().
+  Standard_Boolean Headlight() const { return myIsHeadlight; }
+
+  //! Setup headlight flag.
+  Standard_EXPORT void SetHeadlight (Standard_Boolean theValue);
+
+//! @name positional/spot light properties
+public:
 
-  //! Linear attenuation factor of positional light source
-  Standard_ShortReal  LinearAttenuation() const { return Params.y();  }
+  //! Returns location of positional/spot light; (0, 0, 0) by default.
+  const gp_Pnt& Position() const { return myPosition; }
 
-  //! Const, Linear attenuation factors of positional light source
-  Graphic3d_Vec2      Attenuation()       const { return Params.xy(); }
+  //! Setup location of positional/spot light.
+  Standard_EXPORT void SetPosition (const gp_Pnt& thePosition);
 
-  //! Angle in radians of the cone created by the spot
-  Standard_ShortReal  Angle()             const { return Params.z();  }
+  //! Returns location of positional/spot light.
+  void Position (Standard_Real& theX,
+                 Standard_Real& theY,
+                 Standard_Real& theZ) const
+  {
+    theX = myPosition.X();
+    theY = myPosition.Y();
+    theZ = myPosition.Z();
+  }
 
-  //! Intensity distribution of the spot light, with 0..1 range.
-  Standard_ShortReal  Concentration()     const { return Params.w();  }
+  //! Setup location of positional/spot light.
+  void SetPosition (Standard_Real theX, Standard_Real theY, Standard_Real theZ) { SetPosition (gp_Pnt (theX, theY, theZ)); }
+
+  //! Returns constant attenuation factor of positional/spot light source; 1.0f by default.
+  //! Distance attenuation factors of reducing positional/spot light intensity depending on the distance from its position:
+  //! @code
+  //!   float anAttenuation = 1.0 / (ConstAttenuation() + LinearAttenuation() * theDistance + QuadraticAttenuation() * theDistance * theDistance);
+  //! @endcode
+  Standard_ShortReal ConstAttenuation()  const { return myParams.x(); }
+
+  //! Returns linear attenuation factor of positional/spot light source; 0.0 by default.
+  //! Distance attenuation factors of reducing positional/spot light intensity depending on the distance from its position:
+  //! @code
+  //!   float anAttenuation = 1.0 / (ConstAttenuation() + LinearAttenuation() * theDistance + QuadraticAttenuation() * theDistance * theDistance);
+  //! @endcode
+  Standard_ShortReal LinearAttenuation() const { return myParams.y(); }
+
+  //! Returns the attenuation factors.
+  void Attenuation (Standard_Real& theConstAttenuation,
+                    Standard_Real& theLinearAttenuation) const
+  {
+    theConstAttenuation  = ConstAttenuation();
+    theLinearAttenuation = LinearAttenuation();
+  }
 
-  Standard_ShortReal& ChangeConstAttenuation()  { return Params.x();  }
-  Standard_ShortReal& ChangeLinearAttenuation() { return Params.y();  }
-  Graphic3d_Vec2&     ChangeAttenuation()       { return Params.xy(); }
-  Standard_ShortReal& ChangeAngle()             { return Params.z();  }
-  Standard_ShortReal& ChangeConcentration()     { return Params.w();  }
+  //! Defines the coefficients of attenuation; values should be >= 0.0 and their summ should not be equal to 0.
+  Standard_EXPORT void SetAttenuation (Standard_ShortReal theConstAttenuation,
+                                       Standard_ShortReal theLinearAttenuation);
 
+//! @name directional/spot light additional properties
 public:
 
-  //! Empty constructor
-  Graphic3d_CLight()
-  : Position      (0.0,  0.0,  0.0),
-    Color         (1.0f, 1.0f, 1.0f, 1.0f),
-    Direction     (0.0f, 0.0f, 0.0f, 0.0f),
-    Params        (0.0f, 0.0f, 0.0f, 0.0f),
-    Smoothness    (0.0f),
-    Intensity     (1.0f),
-    Type          (Graphic3d_TOLS_AMBIENT),
-    IsHeadlight   (Standard_False)
+  //! Returns direction of directional/spot light.
+  gp_Dir Direction() const { return gp_Dir (myDirection.x(), myDirection.y(), myDirection.z()); }
+
+  //! Sets direction of directional/spot light.
+  Standard_EXPORT void SetDirection (const gp_Dir& theDir);
+
+  //! Returns the theVx, theVy, theVz direction of the light source.
+  void Direction (Standard_Real& theVx,
+                  Standard_Real& theVy,
+                  Standard_Real& theVz) const
   {
-    //
+    theVx = myDirection.x();
+    theVy = myDirection.y();
+    theVz = myDirection.z();
   }
 
+  //! Sets direction of directional/spot light.
+  void SetDirection (Standard_Real theVx, Standard_Real theVy, Standard_Real theVz) { SetDirection (gp_Dir (theVx, theVy, theVz)); }
+
+//! @name spotlight additional definition parameters
+public:
+
+  //! Returns an angle in radians of the cone created by the spot; 30 degrees by default.
+  Standard_ShortReal Angle() const { return myParams.z(); }
+
+  //! Angle in radians of the cone created by the spot, should be within range (0.0, M_PI).
+  Standard_EXPORT void SetAngle (Standard_ShortReal theAngle);
+
+  //! Returns intensity distribution of the spot light, within [0.0, 1.0] range; 1.0 by default.
+  //! This coefficient should be converted into spotlight exponent within [0.0, 128.0] range:
+  //! @code
+  //!   float aSpotExponent = Concentration() * 128.0;
+  //!   anAttenuation *= pow (aCosA, aSpotExponent);"
+  //! @endcode
+  //! The concentration factor determines the dispersion of the light on the surface, the default value (1.0) corresponds to a minimum of dispersion.
+  Standard_ShortReal Concentration() const { return myParams.w(); }
+
+  //! Defines the coefficient of concentration; value should be within range [0.0, 1.0].
+  Standard_EXPORT void SetConcentration (Standard_ShortReal theConcentration);
+
+//! @name Ray-Tracing / Path-Tracing light properties
 public:
 
-  DEFINE_STANDARD_ALLOC
+  //! Returns the intensity of light source; 1.0 by default.
+  Standard_ShortReal Intensity() const { return myIntensity; }
+
+  //! Modifies the intensity of light source, which should be > 0.0.
+  Standard_EXPORT void SetIntensity (Standard_ShortReal theValue);
+
+  //! Returns the smoothness of light source (either smoothing angle for directional light or smoothing radius in case of positional light); 0.0 by default.
+  Standard_ShortReal Smoothness() const { return mySmoothness; }
+
+  //! Modifies the smoothing radius of positional/spot light; should be >= 0.0.
+  Standard_EXPORT void SetSmoothRadius (Standard_ShortReal theValue);
+
+  //! Modifies the smoothing angle (in radians) of directional light source; should be within range [0.0, M_PI/2].
+  Standard_EXPORT void SetSmoothAngle (Standard_ShortReal theValue);
+
+//! @name low-level access methods
+public:
+
+  //! @return light resource identifier string
+  const TCollection_AsciiString& GetId() const { return myId; }
+
+  //! Packed light parameters.
+  const Graphic3d_Vec4& PackedParams() const { return myParams; }
+
+  //! Returns the color of the light source with dummy Alpha component, which should be ignored.
+  const Graphic3d_Vec4& PackedColor() const { return myColor; }
+
+  //! Returns direction of directional/spot light.
+  const Graphic3d_Vec4& PackedDirection() const { return myDirection; }
+
+  //! @return modification counter
+  Standard_Size Revision() const { return myRevision; }
+
+private:
+
+  //! Access positional/spot light constant attenuation coefficient from packed vector.
+  Standard_ShortReal& changeConstAttenuation()  { return myParams.x(); }
+
+  //! Access positional/spot light linear attenuation coefficient from packed vector.
+  Standard_ShortReal& changeLinearAttenuation() { return myParams.y(); }
+
+  //! Access spotlight angle parameter from packed vector.
+  Standard_ShortReal& changeAngle()             { return myParams.z();  }
+
+  //! Access spotlight concentration parameter from packed vector.
+  Standard_ShortReal& changeConcentration()     { return myParams.w();  }
+
+private:
+
+  //! Generate unique object id.
+  void makeId();
+
+  //! Update modification counter.
+  void updateRevisionIf (bool theIsModified)
+  {
+    if (theIsModified)
+    {
+      ++myRevision;
+    }
+  }
+
+private:
+
+  Graphic3d_CLight (const Graphic3d_CLight& );
+  Graphic3d_CLight& operator= (const Graphic3d_CLight& );
+
+protected:
+
+  TCollection_AsciiString           myId;          //!< resource id
+  TCollection_AsciiString           myName;        //!< user given name
+  gp_Pnt                            myPosition;    //!< light position
+  Quantity_ColorRGBA                myColor;       //!< light color
+  Graphic3d_Vec4                    myDirection;   //!< direction of directional/spot light
+  Graphic3d_Vec4                    myParams;      //!< packed light parameters
+  Standard_ShortReal                mySmoothness;  //!< radius for point light or cone angle for directional light
+  Standard_ShortReal                myIntensity;   //!< intensity multiplier for light
+  const Graphic3d_TypeOfLightSource myType;        //!< Graphic3d_TypeOfLightSource enumeration
+  Standard_Size                     myRevision;    //!< modification counter
+  Standard_Boolean                  myIsHeadlight; //!< flag to mark head light
+  Standard_Boolean                  myIsEnabled;   //!< enabled state
 
 };
 
-typedef NCollection_List<Graphic3d_CLight> Graphic3d_ListOfCLight;
+DEFINE_STANDARD_HANDLE(Graphic3d_CLight, Standard_Transient)
 
 #endif // Graphic3d_CLight_HeaderFile
index 3856bf9..1129c4e 100644 (file)
@@ -409,10 +409,10 @@ public:
   virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) = 0;
 
   //! Returns list of lights of the view.
-  virtual const Graphic3d_ListOfCLight& Lights() const = 0;
+  virtual const Handle(Graphic3d_LightSet)& Lights() const = 0;
 
   //! Sets list of lights for the view.
-  virtual void SetLights (const Graphic3d_ListOfCLight& theLights) = 0;
+  virtual void SetLights (const Handle(Graphic3d_LightSet)& theLights) = 0;
 
   //! Returns list of clip planes set for the view.
   virtual const Handle(Graphic3d_SequenceOfHClipPlane)& ClipPlanes() const = 0;
diff --git a/src/Graphic3d/Graphic3d_LightSet.cxx b/src/Graphic3d/Graphic3d_LightSet.cxx
new file mode 100644 (file)
index 0000000..0b51b70
--- /dev/null
@@ -0,0 +1,146 @@
+// Copyright (c) 2017 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 <Graphic3d_LightSet.hxx>
+
+#include <NCollection_LocalArray.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient)
+
+namespace
+{
+  //! Suffixes identifying light source type.
+  static const char THE_LIGHT_KEY_LETTERS[Graphic3d_TypeOfLightSource_NB] =
+  {
+    'a', // Graphic3d_TOLS_AMBIENT
+    'd', // Graphic3d_TOLS_DIRECTIONAL
+    'p', // Graphic3d_TOLS_POSITIONAL
+    's'  // Graphic3d_TOLS_SPOT
+  };
+}
+
+// =======================================================================
+// function : Graphic3d_LightSet
+// purpose  :
+// =======================================================================
+Graphic3d_LightSet::Graphic3d_LightSet()
+: myAmbient (0.0f, 0.0f, 0.0f, 0.0f),
+  myNbEnabled (0),
+  myRevision (1),
+  myCacheRevision (0)
+{
+  memset (myLightTypes,        0, sizeof(myLightTypes));
+  memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
+}
+
+// =======================================================================
+// function : Add
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_LightSet::Add (const Handle(Graphic3d_CLight)& theLight)
+{
+  if (theLight.IsNull())
+  {
+    throw Standard_ProgramError ("Graphic3d_LightSet::Add(), NULL argument");
+  }
+
+  const Standard_Integer anOldExtent = myLights.Extent();
+  const Standard_Integer anIndex     = myLights.Add (theLight, 0);
+  if (anIndex <= anOldExtent)
+  {
+    return Standard_False;
+  }
+
+  myLightTypes[theLight->Type()] += 1;
+  myLights.ChangeFromIndex (anIndex) = theLight->Revision();
+  ++myRevision;
+  return Standard_True;
+}
+
+// =======================================================================
+// function : Remove
+// purpose  :
+// =======================================================================
+Standard_Boolean Graphic3d_LightSet::Remove (const Handle(Graphic3d_CLight)& theLight)
+{
+  const Standard_Integer anIndToRemove = myLights.FindIndex (theLight);
+  if (anIndToRemove <= 0)
+  {
+    return Standard_False;
+  }
+
+  ++myRevision;
+  myLights.RemoveFromIndex (anIndToRemove);
+  myLightTypes[theLight->Type()] -= 1;
+  return Standard_True;
+}
+
+// =======================================================================
+// function : UpdateRevision
+// purpose  :
+// =======================================================================
+Standard_Size Graphic3d_LightSet::UpdateRevision()
+{
+  if (myCacheRevision == myRevision)
+  {
+    // check implicit updates of light sources
+    for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
+    {
+      const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
+      if (aLightIter.Value() != aLight->Revision())
+      {
+        ++myRevision;
+        break;
+      }
+    }
+  }
+  if (myCacheRevision == myRevision)
+  {
+    return myRevision;
+  }
+
+  myCacheRevision = myRevision;
+  myAmbient.SetValues (0.0f, 0.0f, 0.0f, 0.0f);
+  memset (myLightTypesEnabled, 0, sizeof(myLightTypesEnabled));
+  NCollection_LocalArray<char, 32> aKeyLong (myLights.Extent() + 1);
+  Standard_Integer aLightLast = 0;
+  for (NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator aLightIter (myLights); aLightIter.More(); aLightIter.Next())
+  {
+    const Handle(Graphic3d_CLight)& aLight = aLightIter.Key();
+    aLightIter.ChangeValue() = aLight->Revision();
+    if (!aLight->IsEnabled())
+    {
+      continue;
+    }
+
+    myLightTypesEnabled[aLight->Type()] += 1;
+    if (aLight->Type() == Graphic3d_TOLS_AMBIENT)
+    {
+      myAmbient += aLight->PackedColor() * aLight->Intensity();
+    }
+    else
+    {
+      aKeyLong[aLightLast++] = THE_LIGHT_KEY_LETTERS[aLight->Type()];
+    }
+  }
+  aKeyLong[aLightLast] = '\0';
+  myAmbient.a() = 1.0f;
+  myNbEnabled = myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL]
+              + myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL]
+              + myLightTypesEnabled[Graphic3d_TOLS_SPOT];
+  myKeyEnabledLong  = aKeyLong;
+  myKeyEnabledShort = TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_DIRECTIONAL] > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_DIRECTIONAL] : '\0')
+                    + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_POSITIONAL]  > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_POSITIONAL]  : '\0')
+                    + TCollection_AsciiString (myLightTypesEnabled[Graphic3d_TOLS_SPOT]        > 0 ? THE_LIGHT_KEY_LETTERS[Graphic3d_TOLS_SPOT]        : '\0');
+  return myRevision;
+}
diff --git a/src/Graphic3d/Graphic3d_LightSet.hxx b/src/Graphic3d/Graphic3d_LightSet.hxx
new file mode 100644 (file)
index 0000000..418cdcc
--- /dev/null
@@ -0,0 +1,190 @@
+// Copyright (c) 2017 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.
+
+#ifndef _Graphic3d_LightSet_HeaderFile
+#define _Graphic3d_LightSet_HeaderFile
+
+#include <NCollection_IndexedDataMap.hxx>
+#include <Graphic3d_CLight.hxx>
+
+//! Class defining the set of light sources.
+class Graphic3d_LightSet : public Standard_Transient
+{
+  DEFINE_STANDARD_RTTIEXT(Graphic3d_LightSet, Standard_Transient)
+public:
+
+  //! Iteration filter flags.
+  enum IterationFilter
+  {
+    IterationFilter_None            = 0x0000, //!< no filter
+    IterationFilter_ExcludeAmbient  = 0x0002, //!< exclude ambient  light sources
+    IterationFilter_ExcludeDisabled = 0x0004, //!< exclude disabled light sources
+    IterationFilter_ExcludeDisabledAndAmbient = IterationFilter_ExcludeAmbient | IterationFilter_ExcludeDisabled,
+  };
+
+  //! Iterator through light sources.
+  class Iterator
+  {
+  public:
+    //! Empty constructor.
+    Iterator() : myFilter (0) {}
+
+    //! Constructor with initialization.
+    Iterator (const Graphic3d_LightSet& theSet,
+              IterationFilter theFilter = IterationFilter_None)
+    : myIter (theSet.myLights),
+      myFilter (theFilter)
+    {
+      skipFiltered();
+    }
+
+    //! Constructor with initialization.
+    Iterator (const Handle(Graphic3d_LightSet)& theSet,
+              IterationFilter theFilter = IterationFilter_None)
+    : myFilter (theFilter)
+    {
+      if (!theSet.IsNull())
+      {
+        myIter = NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator (theSet->myLights);
+        skipFiltered();
+      }
+    }
+
+    //! Returns TRUE if iterator points to a valid item.
+    Standard_Boolean More() const { return myIter.More(); }
+
+    //! Returns current item.
+    const Handle(Graphic3d_CLight)& Value() const { return myIter.Key(); }
+
+    //! Moves to the next item.
+    void Next()
+    {
+      myIter.Next();
+      skipFiltered();
+    }
+
+  protected:
+
+    //! Skip filtered items.
+    void skipFiltered()
+    {
+      if (myFilter == 0)
+      {
+        return;
+      }
+
+      for (; myIter.More(); myIter.Next())
+      {
+        if ((myFilter & IterationFilter_ExcludeAmbient) != 0
+         && myIter.Key()->Type() == Graphic3d_TOLS_AMBIENT)
+        {
+          continue;
+        }
+        else if ((myFilter & IterationFilter_ExcludeDisabled) != 0
+              && !myIter.Key()->IsEnabled())
+        {
+          continue;
+        }
+
+        break;
+      }
+    }
+
+  protected:
+    NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>::Iterator myIter;
+    Standard_Integer myFilter;
+  };
+
+public:
+
+  //! Empty constructor.
+  Standard_EXPORT Graphic3d_LightSet();
+
+  //! Return lower light index.
+  Standard_Integer Lower() const { return 1; }
+
+  //! Return upper light index.
+  Standard_Integer Upper() const { return myLights.Extent(); }
+
+  //! Return TRUE if lights list is empty.
+  Standard_Boolean IsEmpty() const { return myLights.IsEmpty(); }
+
+  //! Return number of light sources.
+  Standard_Integer Extent() const { return myLights.Extent(); }
+
+  //! Return the light source for specified index within range [Lower(), Upper()].
+  const Handle(Graphic3d_CLight)& Value (Standard_Integer theIndex) const { return myLights.FindKey (theIndex); }
+
+  //! Return TRUE if light source is defined in this set.
+  Standard_Boolean Contains (const Handle(Graphic3d_CLight)& theLight) const { return myLights.Contains (theLight); }
+
+  //! Append new light source.
+  Standard_EXPORT Standard_Boolean Add (const Handle(Graphic3d_CLight)& theLight);
+
+  //! Remove light source.
+  Standard_EXPORT Standard_Boolean Remove (const Handle(Graphic3d_CLight)& theLight);
+
+  //! Returns total amount of lights of specified type.
+  Standard_Integer NbLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypes[theType]; }
+
+//! @name cached state of lights set updated by UpdateRevision()
+public:
+
+  //! Update light sources revision.
+  Standard_EXPORT Standard_Size UpdateRevision();
+
+  //! Return light sources revision.
+  //! @sa UpdateRevision()
+  Standard_Size Revision() const { return myRevision; }
+
+  //! Returns total amount of enabled lights EXCLUDING ambient.
+  //! @sa UpdateRevision()
+  Standard_Integer NbEnabled() const { return myNbEnabled; }
+
+  //! Returns total amount of enabled lights of specified type.
+  //! @sa UpdateRevision()
+  Standard_Integer NbEnabledLightsOfType (Graphic3d_TypeOfLightSource theType) const { return myLightTypesEnabled[theType]; }
+
+  //! Returns cumulative ambient color, which is computed as sum of all enabled ambient light sources.
+  //! Values are NOT clamped (can be greater than 1.0f) and alpha component is fixed to 1.0f.
+  //! @sa UpdateRevision()
+  const Graphic3d_Vec4& AmbientColor() const { return myAmbient; }
+
+  //! Returns a string defining a list of enabled light sources as concatenation of letters 'd' (Directional), 'p' (Point), 's' (Spot)
+  //! depending on the type of light source in the list.
+  //! Example: "dppp".
+  //! @sa UpdateRevision()
+  const TCollection_AsciiString& KeyEnabledLong() const { return myKeyEnabledLong; }
+
+  //! Returns a string defining a list of enabled light sources as concatenation of letters 'd' (Directional), 'p' (Point), 's' (Spot)
+  //! depending on the type of light source in the list, specified only once.
+  //! Example: "dp".
+  //! @sa UpdateRevision()
+  const TCollection_AsciiString& KeyEnabledShort() const { return myKeyEnabledShort; }
+
+protected:
+  NCollection_IndexedDataMap<Handle(Graphic3d_CLight), Standard_Size>
+                          myLights;                 //!< list of light sources with their cached state (revision)
+  Graphic3d_Vec4          myAmbient;                //!< cached value of cumulative ambient color
+  TCollection_AsciiString myKeyEnabledLong;         //!< key identifying the list of enabled light sources by their type
+  TCollection_AsciiString myKeyEnabledShort;        //!< key identifying the list of enabled light sources by the number of sources of each type
+  Standard_Integer        myLightTypes       [Graphic3d_TypeOfLightSource_NB]; //!< counters per each light source type defined in the list
+  Standard_Integer        myLightTypesEnabled[Graphic3d_TypeOfLightSource_NB]; //!< counters per each light source type enabled in the list
+  Standard_Integer        myNbEnabled;              //!< number of enabled light sources, excluding ambient
+  Standard_Size           myRevision;               //!< current revision of light source set
+  Standard_Size           myCacheRevision;          //!< revision of cached state
+};
+
+DEFINE_STANDARD_HANDLE(Graphic3d_LightSet, Standard_Transient)
+
+#endif // _Graphic3d_LightSet_HeaderFile
index 17a923a..4f4e43b 100644 (file)
 #ifndef _Graphic3d_TypeOfLightSource_HeaderFile
 #define _Graphic3d_TypeOfLightSource_HeaderFile
 
-//! Definition of all the type of light sources
-//!
-//! TOLS_AMBIENT    ambient light
-//! TOLS_DIRECTIONAL    directional light
-//! TOLS_POSITIONAL positional light
-//! TOLS_SPOT       spot light
+//! Definition of all the type of light source.
 enum Graphic3d_TypeOfLightSource
 {
-  Graphic3d_TOLS_AMBIENT,
-  Graphic3d_TOLS_DIRECTIONAL,
-  Graphic3d_TOLS_POSITIONAL,
-  Graphic3d_TOLS_SPOT
+  Graphic3d_TOLS_AMBIENT,     //!< ambient light
+  Graphic3d_TOLS_DIRECTIONAL, //!< directional light
+  Graphic3d_TOLS_POSITIONAL,  //!< positional light
+  Graphic3d_TOLS_SPOT,        //!< spot light
+  // obsolete aliases
+  V3d_AMBIENT     = Graphic3d_TOLS_AMBIENT,
+  V3d_DIRECTIONAL = Graphic3d_TOLS_DIRECTIONAL,
+  V3d_POSITIONAL  = Graphic3d_TOLS_POSITIONAL,
+  V3d_SPOT        = Graphic3d_TOLS_SPOT
+};
+
+enum
+{
+  //! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfLightSource
+  Graphic3d_TypeOfLightSource_NB = Graphic3d_TOLS_SPOT + 1
 };
 
 #endif // _Graphic3d_TypeOfLightSource_HeaderFile
index b889d4c..0712618 100644 (file)
@@ -30,4 +30,10 @@ enum Graphic3d_TypeOfShadingModel
   Graphic3d_TOSM_FRAGMENT
 };
 
+enum
+{
+  //! Auxiliary value defining the overall number of values in enumeration Graphic3d_TypeOfShadingModel
+  Graphic3d_TypeOfShadingModel_NB = Graphic3d_TOSM_FRAGMENT + 1
+};
+
 #endif // _Graphic3d_TypeOfShadingModel_HeaderFile
index 826ee0a..c7eab89 100644 (file)
@@ -16,6 +16,7 @@
 
 #include <gp_XYZ.hxx>
 #include <Geom_Transformation.hxx>
+#include <Graphic3d_LightSet.hxx>
 #include <Graphic3d_PolygonOffset.hxx>
 #include <TCollection_AsciiString.hxx>
 
@@ -48,6 +49,13 @@ struct Graphic3d_ZLayerSettings
   //! Set custom name.
   void SetName (const TCollection_AsciiString& theName) { myName = theName; }
 
+  //! Return lights list to be used for rendering presentations within this Z-Layer; NULL by default.
+  //! NULL list (but not empty list!) means that default lights assigned to the View should be used instead of per-layer lights.
+  const Handle(Graphic3d_LightSet)& Lights() const { return myLights; }
+
+  //! Assign lights list to be used.
+  void SetLights (const Handle(Graphic3d_LightSet)& theLights) { myLights = theLights; }
+
   //! Return the origin of all objects within the layer.
   const gp_XYZ& Origin() const { return myOrigin; }
 
@@ -193,6 +201,7 @@ struct Graphic3d_ZLayerSettings
 protected:
 
   TCollection_AsciiString     myName;                  //!< user-provided name
+  Handle(Graphic3d_LightSet)  myLights;                //!< lights list
   Handle(Geom_Transformation) myOriginTrsf;            //!< transformation to the origin
   gp_XYZ                      myOrigin;                //!< the origin of all objects within the layer
   Standard_Real               myCullingDistance;       //!< distance to discard objects
index 6159780..64fa0de 100755 (executable)
@@ -33,7 +33,6 @@ OpenGl_View.hxx
 OpenGl_View.cxx
 OpenGl_View_Raytrace.cxx
 OpenGl_View_Redraw.cxx
-OpenGl_Light.hxx
 OpenGl_GraduatedTrihedron.hxx
 OpenGl_GraduatedTrihedron.cxx
 OpenGl_MapOfZLayerSettings.hxx
index e5e94cf..929c927 100644 (file)
@@ -680,6 +680,15 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)&   theWorkspace,
 
   const Standard_Boolean hasLocalCS = !myLayerSettings.OriginTransformation().IsNull();
   const Handle(OpenGl_Context)&   aCtx         = theWorkspace->GetGlContext();
+  const Handle(OpenGl_ShaderManager)& aManager = aCtx->ShaderManager();
+  Handle(Graphic3d_LightSet) aLightsBack = aManager->LightSourceState().LightSources();
+  const bool hasOwnLights = aCtx->ColorMask() && !myLayerSettings.Lights().IsNull() && myLayerSettings.Lights() != aLightsBack;
+  if (hasOwnLights)
+  {
+    myLayerSettings.Lights()->UpdateRevision();
+    aManager->UpdateLightSourceStateTo (myLayerSettings.Lights());
+  }
+
   const Handle(Graphic3d_Camera)& aWorldCamera = theWorkspace->View()->Camera();
   if (hasLocalCS)
   {
@@ -731,6 +740,10 @@ void OpenGl_Layer::Render (const Handle(OpenGl_Workspace)&   theWorkspace,
   // render priority list
   renderAll (theWorkspace);
 
+  if (hasOwnLights)
+  {
+    aManager->UpdateLightSourceStateTo (aLightsBack);
+  }
   if (hasLocalCS)
   {
     aCtx->ShaderManager()->RevertClippingState();
index 51dbc60..4bcd58a 100644 (file)
@@ -568,6 +568,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
   Standard_Integer aClearDepthLayerPrev = -1, aClearDepthLayer = -1;
   const bool toPerformDepthPrepass = theWorkspace->View()->RenderingParams().ToEnableDepthPrepass
                                   && aPrevSettings.DepthMask == GL_TRUE;
+  const Handle(Graphic3d_LightSet) aLightsBack = aCtx->ShaderManager()->LightSourceState().LightSources();
   for (OpenGl_FilteredIndexedLayerIterator aLayerIterStart (myLayers, myDefaultLayerIndex, theToDrawImmediate, theLayersToProcess); aLayerIterStart.More();)
   {
     bool hasSkippedDepthLayers = false;
@@ -576,6 +577,7 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
       if (aPassIter == 0)
       {
         aCtx->SetColorMask (false);
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (Handle(Graphic3d_LightSet)());
         aDefaultSettings.DepthFunc = aPrevSettings.DepthFunc;
         aDefaultSettings.DepthMask = GL_TRUE;
       }
@@ -586,11 +588,13 @@ void OpenGl_LayerList::Render (const Handle(OpenGl_Workspace)& theWorkspace,
           continue;
         }
         aCtx->SetColorMask (true);
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
         aDefaultSettings = aPrevSettings;
       }
       else if (aPassIter == 2)
       {
         aCtx->SetColorMask (true);
+        aCtx->ShaderManager()->UpdateLightSourceStateTo (aLightsBack);
         if (toPerformDepthPrepass)
         {
           aDefaultSettings.DepthFunc = GL_EQUAL;
diff --git a/src/OpenGl/OpenGl_Light.hxx b/src/OpenGl/OpenGl_Light.hxx
deleted file mode 100644 (file)
index d1c0c36..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-// Created on: 2011-07-13
-// Created by: Sergey ZERCHANINOV
-// Copyright (c) 2011-2014 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.
-
-#ifndef OpenGl_Light_Header
-#define OpenGl_Light_Header
-
-#include <Graphic3d_CLight.hxx>
-#include <NCollection_List.hxx>
-
-#define OpenGLMaxLights 8
-
-typedef Graphic3d_CLight       OpenGl_Light;
-typedef Graphic3d_ListOfCLight OpenGl_ListOfLight;
-
-#endif // OpenGl_Light_Header
index 6b72d90..530bf57 100644 (file)
@@ -108,7 +108,7 @@ OpenGl_RaytraceMaterial::OpenGl_RaytraceMaterial (const BVH_Vec4f& theAmbient,
 }
 
 // =======================================================================
-// function : OpenGl_LightSource
+// function : OpenGl_RaytraceLight
 // purpose  : Creates new light source
 // =======================================================================
 OpenGl_RaytraceLight::OpenGl_RaytraceLight (const BVH_Vec4f& theEmission,
index 5faea41..fe84cac 100644 (file)
@@ -32,6 +32,25 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_ShaderManager,Standard_Transient)
 
 namespace
 {
+  //! Suffixes identifying shading model.
+  static const char THE_SHADINGMODEL_KEY_LETTERS[Graphic3d_TypeOfShadingModel_NB] =
+  {
+    'c', // Graphic3d_TOSM_NONE
+    'f', // Graphic3d_TOSM_FACET
+    'g', // Graphic3d_TOSM_VERTEX
+    'p'  // Graphic3d_TOSM_FRAGMENT
+  };
+
+  //! Number specifying maximum number of light sources to prepare a GLSL program with unrolled loop.
+  const Standard_Integer THE_NB_UNROLLED_LIGHTS_MAX = 32;
+
+  //! Compute the size of array storing holding light sources definition.
+  static Standard_Integer roundUpMaxLightSources (Standard_Integer theNbLights)
+  {
+    Standard_Integer aMaxLimit = THE_NB_UNROLLED_LIGHTS_MAX;
+    for (; aMaxLimit < theNbLights; aMaxLimit *= 2) {}
+    return aMaxLimit;
+  }
 
 #define EOL "\n"
 
@@ -260,31 +279,32 @@ const char THE_FRAG_write_oit_buffers[] =
   static const GLfloat THE_DEFAULT_SPOT_CUTOFF   = 180.0f;
 
   //! Bind FFP light source.
-  static void bindLight (const OpenGl_Light& theLight,
+  static void bindLight (const Graphic3d_CLight& theLight,
                          const GLenum        theLightGlId,
                          const OpenGl_Mat4&  theModelView,
                          OpenGl_Context*     theCtx)
   {
     // the light is a headlight?
-    if (theLight.IsHeadlight)
+    if (theLight.IsHeadlight())
     {
       theCtx->core11->glMatrixMode (GL_MODELVIEW);
       theCtx->core11->glLoadIdentity();
     }
 
     // setup light type
-    switch (theLight.Type)
+    const Graphic3d_Vec4& aLightColor = theLight.PackedColor();
+    switch (theLight.Type())
     {
       case Graphic3d_TOLS_AMBIENT    : break; // handled by separate if-clause at beginning of method
       case Graphic3d_TOLS_DIRECTIONAL:
       {
         // if the last parameter of GL_POSITION, is zero, the corresponding light source is a Directional one
-        const OpenGl_Vec4 anInfDir = -theLight.Direction;
+        const OpenGl_Vec4 anInfDir = -theLight.PackedDirection();
 
         // to create a realistic effect,  set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE.
         theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
-        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
-        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               aLightColor.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              aLightColor.GetData());
         theCtx->core11->glLightfv (theLightGlId, GL_POSITION,              anInfDir.GetData());
         theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION,        THE_DEFAULT_SPOT_DIR);
         theCtx->core11->glLightf  (theLightGlId, GL_SPOT_EXPONENT,         THE_DEFAULT_SPOT_EXPONENT);
@@ -294,10 +314,10 @@ const char THE_FRAG_write_oit_buffers[] =
       case Graphic3d_TOLS_POSITIONAL:
       {
         // to create a realistic effect, set the GL_SPECULAR parameter to the same value as the GL_DIFFUSE
-        const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
+        const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position().X()), static_cast<float>(theLight.Position().Y()), static_cast<float>(theLight.Position().Z()), 1.0f);
         theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
-        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
-        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               aLightColor.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              aLightColor.GetData());
         theCtx->core11->glLightfv (theLightGlId, GL_POSITION,              aPosition.GetData());
         theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION,        THE_DEFAULT_SPOT_DIR);
         theCtx->core11->glLightf  (theLightGlId, GL_SPOT_EXPONENT,         THE_DEFAULT_SPOT_EXPONENT);
@@ -309,12 +329,12 @@ const char THE_FRAG_write_oit_buffers[] =
       }
       case Graphic3d_TOLS_SPOT:
       {
-        const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position.x()), static_cast<float>(theLight.Position.y()), static_cast<float>(theLight.Position.z()), 1.0f);
+        const OpenGl_Vec4 aPosition (static_cast<float>(theLight.Position().X()), static_cast<float>(theLight.Position().Y()), static_cast<float>(theLight.Position().Z()), 1.0f);
         theCtx->core11->glLightfv (theLightGlId, GL_AMBIENT,               THE_DEFAULT_AMBIENT);
-        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               theLight.Color.GetData());
-        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              theLight.Color.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_DIFFUSE,               aLightColor.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_SPECULAR,              aLightColor.GetData());
         theCtx->core11->glLightfv (theLightGlId, GL_POSITION,              aPosition.GetData());
-        theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION,        theLight.Direction.GetData());
+        theCtx->core11->glLightfv (theLightGlId, GL_SPOT_DIRECTION,        theLight.PackedDirection().GetData());
         theCtx->core11->glLightf  (theLightGlId, GL_SPOT_EXPONENT,         theLight.Concentration() * 128.0f);
         theCtx->core11->glLightf  (theLightGlId, GL_SPOT_CUTOFF,          (theLight.Angle() * 180.0f) / GLfloat(M_PI));
         theCtx->core11->glLightf  (theLightGlId, GL_CONSTANT_ATTENUATION,  theLight.ConstAttenuation());
@@ -325,7 +345,7 @@ const char THE_FRAG_write_oit_buffers[] =
     }
 
     // restore matrix in case of headlight
-    if (theLight.IsHeadlight)
+    if (theLight.IsHeadlight())
     {
       theCtx->core11->glLoadMatrixf (theModelView.GetData());
     }
@@ -476,35 +496,28 @@ Standard_Boolean OpenGl_ShaderManager::IsEmpty() const
 // =======================================================================
 void OpenGl_ShaderManager::switchLightPrograms()
 {
+  const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources();
   TCollection_AsciiString aKey;
-  switch (myShadingModel)
-  {
-    case Graphic3d_TOSM_NONE:     aKey = "c_"; break;
-    case Graphic3d_TOSM_FACET:    aKey = "f_"; break;
-    case Graphic3d_TOSM_VERTEX:   aKey = "g_"; break;
-    case Graphic3d_TOSM_FRAGMENT: aKey = "p_"; break;
-  }
-  const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
-  if (aLights != NULL)
+  if (!aLights.IsNull())
   {
-    for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next())
+    aKey = THE_SHADINGMODEL_KEY_LETTERS[myShadingModel];
+    aKey += "_";
+    if (aLights->NbEnabled() <= THE_NB_UNROLLED_LIGHTS_MAX)
     {
-      switch (aLightIter.Value().Type)
-      {
-        case Graphic3d_TOLS_AMBIENT:
-          break; // skip ambient
-        case Graphic3d_TOLS_DIRECTIONAL:
-          aKey += "d";
-          break;
-        case Graphic3d_TOLS_POSITIONAL:
-          aKey += "p";
-          break;
-        case Graphic3d_TOLS_SPOT:
-          aKey += "s";
-          break;
-      }
+      aKey += aLights->KeyEnabledLong();
+    }
+    else
+    {
+      const Standard_Integer aMaxLimit = roundUpMaxLightSources (aLights->NbEnabled());
+      aKey += aLights->KeyEnabledShort();
+      aKey += aMaxLimit;
     }
   }
+  else
+  {
+    aKey = THE_SHADINGMODEL_KEY_LETTERS[Graphic3d_TOSM_NONE];
+    aKey += "_";
+  }
 
   if (!myMapOfLightPrograms.Find (aKey, myLightPrograms))
   {
@@ -517,7 +530,7 @@ void OpenGl_ShaderManager::switchLightPrograms()
 // function : UpdateLightSourceStateTo
 // purpose  : Updates state of OCCT light sources
 // =======================================================================
-void OpenGl_ShaderManager::UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights)
+void OpenGl_ShaderManager::UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights)
 {
   myLightSourceState.Set (theLights);
   myLightSourceState.Update();
@@ -594,32 +607,25 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
     }
 
     GLenum aLightGlId = GL_LIGHT0;
-    OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
     const OpenGl_Mat4 aModelView = myWorldViewState.WorldViewMatrix() * myModelWorldState.ModelWorldMatrix();
-    if (myLightSourceState.LightSources() != NULL)
+    for (Graphic3d_LightSet::Iterator aLightIt (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
+         aLightIt.More(); aLightIt.Next())
     {
-      for (Graphic3d_ListOfCLight::Iterator aLightIt (*myLightSourceState.LightSources()); aLightIt.More(); aLightIt.Next())
+      if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP...
       {
-        const Graphic3d_CLight& aLight = aLightIt.Value();
-        if (aLight.Type == Graphic3d_TOLS_AMBIENT)
-        {
-          anAmbient += aLight.Color;
-          continue;
-        }
-        else if (aLightGlId > GL_LIGHT7) // only 8 lights in FFP...
-        {
-          myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
-                                  "Warning: light sources limit (8) has been exceeded within Fixed-function pipeline.");
-          continue;
-        }
-
-        bindLight (aLight, aLightGlId, aModelView, myContext);
-        ++aLightGlId;
+        myContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_MEDIUM,
+                                "Warning: light sources limit (8) has been exceeded within Fixed-function pipeline.");
+        continue;
       }
+
+      bindLight (*aLightIt.Value(), aLightGlId, aModelView, myContext);
+      ++aLightGlId;
     }
 
     // apply accumulated ambient color
-    anAmbient.a() = 1.0f;
+    const Graphic3d_Vec4 anAmbient = !myLightSourceState.LightSources().IsNull()
+                                    ? myLightSourceState.LightSources()->AmbientColor()
+                                    : Graphic3d_Vec4 (0.0f, 0.0f, 0.0f, 1.0f);
     myContext->core11->glLightModelfv (GL_LIGHT_MODEL_AMBIENT, anAmbient.GetData());
 
     // GL_LIGHTING is managed by drawers to switch between shaded / no lighting output,
@@ -659,7 +665,7 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
     myLightTypeArray.ChangeValue (aLightIt).Type = -1;
   }
 
-  if (myLightSourceState.LightSources() == NULL
+  if (myLightSourceState.LightSources().IsNull()
    || myLightSourceState.LightSources()->IsEmpty())
   {
     theProgram->SetUniform (myContext,
@@ -675,17 +681,12 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
     return;
   }
 
-  OpenGl_Vec4 anAmbient (0.0f, 0.0f, 0.0f, 0.0f);
   Standard_Integer aLightsNb = 0;
-  for (OpenGl_ListOfLight::Iterator anIter (*myLightSourceState.LightSources()); anIter.More(); anIter.Next())
+  for (Graphic3d_LightSet::Iterator anIter (myLightSourceState.LightSources(), Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
+       anIter.More(); anIter.Next())
   {
-    const OpenGl_Light& aLight = anIter.Value();
-    if (aLight.Type == Graphic3d_TOLS_AMBIENT)
-    {
-      anAmbient += aLight.Color;
-      continue;
-    }
-    else if (aLightsNb >= aNbLightsMax)
+    const Graphic3d_CLight& aLight = *anIter.Value();
+    if (aLightsNb >= aNbLightsMax)
     {
       if (aNbLightsMax != 0)
       {
@@ -697,36 +698,47 @@ void OpenGl_ShaderManager::PushLightSourceState (const Handle(OpenGl_ShaderProgr
 
     OpenGl_ShaderLightType&       aLightType   = myLightTypeArray.ChangeValue (aLightsNb);
     OpenGl_ShaderLightParameters& aLightParams = myLightParamsArray.ChangeValue (aLightsNb);
-    aLightType.Type        = aLight.Type;
-    aLightType.IsHeadlight = aLight.IsHeadlight;
-    aLightParams.Color     = aLight.Color;
-    if (aLight.Type == Graphic3d_TOLS_DIRECTIONAL)
+    if (!aLight.IsEnabled()) // has no affect with Graphic3d_LightSet::IterationFilter_ExcludeDisabled - here just for consistency
     {
-      aLightParams.Position = -aLight.Direction;
+      // if it is desired to keep disabled light in the same order - we can replace it with a black light so that it will have no influence on result
+      aLightType.Type        = -1; // Graphic3d_TOLS_AMBIENT can be used instead
+      aLightType.IsHeadlight = false;
+      aLightParams.Color     = OpenGl_Vec4 (0.0f, 0.0f, 0.0f, 0.0f);
+      ++aLightsNb;
+      continue;
     }
-    else if (!aLight.IsHeadlight)
+
+    aLightType.Type        = aLight.Type();
+    aLightType.IsHeadlight = aLight.IsHeadlight();
+    aLightParams.Color     = aLight.PackedColor();
+    if (aLight.Type() == Graphic3d_TOLS_DIRECTIONAL)
     {
-      aLightParams.Position.x() = static_cast<float>(aLight.Position.x() - myLocalOrigin.X());
-      aLightParams.Position.y() = static_cast<float>(aLight.Position.y() - myLocalOrigin.Y());
-      aLightParams.Position.z() = static_cast<float>(aLight.Position.z() - myLocalOrigin.Z());
+      aLightParams.Position = -aLight.PackedDirection();
+    }
+    else if (!aLight.IsHeadlight())
+    {
+      aLightParams.Position.x() = static_cast<float>(aLight.Position().X() - myLocalOrigin.X());
+      aLightParams.Position.y() = static_cast<float>(aLight.Position().Y() - myLocalOrigin.Y());
+      aLightParams.Position.z() = static_cast<float>(aLight.Position().Z() - myLocalOrigin.Z());
       aLightParams.Position.w() = 1.0f;
     }
     else
     {
-      aLightParams.Position.x() = static_cast<float>(aLight.Position.x());
-      aLightParams.Position.y() = static_cast<float>(aLight.Position.y());
-      aLightParams.Position.z() = static_cast<float>(aLight.Position.z());
+      aLightParams.Position.x() = static_cast<float>(aLight.Position().X());
+      aLightParams.Position.y() = static_cast<float>(aLight.Position().Y());
+      aLightParams.Position.z() = static_cast<float>(aLight.Position().Z());
       aLightParams.Position.w() = 1.0f;
     }
 
-    if (aLight.Type == Graphic3d_TOLS_SPOT)
+    if (aLight.Type() == Graphic3d_TOLS_SPOT)
     {
-      aLightParams.Direction = aLight.Direction;
+      aLightParams.Direction = aLight.PackedDirection();
     }
-    aLightParams.Parameters = aLight.Params;
+    aLightParams.Parameters = aLight.PackedParams();
     ++aLightsNb;
   }
 
+  const Graphic3d_Vec4& anAmbient = myLightSourceState.LightSources()->AmbientColor();
   theProgram->SetUniform (myContext,
                           theProgram->GetStateLocation (OpenGl_OCC_LIGHT_SOURCE_COUNT),
                           aLightsNb);
@@ -1664,52 +1676,96 @@ TCollection_AsciiString OpenGl_ShaderManager::pointSpriteShadingSrc (const TColl
 TCollection_AsciiString OpenGl_ShaderManager::stdComputeLighting (Standard_Integer& theNbLights,
                                                                   Standard_Boolean  theHasVertColor)
 {
-  Standard_Integer aLightsMap[Graphic3d_TOLS_SPOT + 1] = { 0, 0, 0, 0 };
   TCollection_AsciiString aLightsFunc, aLightsLoop;
-  const OpenGl_ListOfLight* aLights = myLightSourceState.LightSources();
-  if (aLights != NULL)
   theNbLights = 0;
+  const Handle(Graphic3d_LightSet)& aLights = myLightSourceState.LightSources();
+  if (!aLights.IsNull())
   {
-    Standard_Integer anIndex = 0;
-    for (OpenGl_ListOfLight::Iterator aLightIter (*aLights); aLightIter.More(); aLightIter.Next(), ++anIndex)
+    theNbLights = aLights->NbEnabled();
+    if (theNbLights <= THE_NB_UNROLLED_LIGHTS_MAX)
+    {
+      Standard_Integer anIndex = 0;
+      for (Graphic3d_LightSet::Iterator aLightIter (aLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
+           aLightIter.More(); aLightIter.Next(), ++anIndex)
+      {
+        switch (aLightIter.Value()->Type())
+        {
+          case Graphic3d_TOLS_AMBIENT:
+            --anIndex;
+            break; // skip ambient
+          case Graphic3d_TOLS_DIRECTIONAL:
+            aLightsLoop = aLightsLoop + EOL"    directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
+            break;
+          case Graphic3d_TOLS_POSITIONAL:
+            aLightsLoop = aLightsLoop + EOL"    pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
+            break;
+          case Graphic3d_TOLS_SPOT:
+            aLightsLoop = aLightsLoop + EOL"    spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
+            break;
+        }
+      }
+    }
+    else
     {
-      switch (aLightIter.Value().Type)
+      theNbLights = roundUpMaxLightSources (theNbLights);
+      bool isFirstInLoop = true;
+      aLightsLoop = aLightsLoop +
+        EOL"    for (int anIndex = 0; anIndex < occLightSourcesCount; ++anIndex)"
+        EOL"    {"
+        EOL"      int aType = occLight_Type (anIndex);";
+      if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
       {
-        case Graphic3d_TOLS_AMBIENT:
-          --anIndex;
-          break; // skip ambient
-        case Graphic3d_TOLS_DIRECTIONAL:
-          aLightsLoop = aLightsLoop + EOL"    directionalLight (" + anIndex + ", theNormal, theView, theIsFront);";
-          break;
-        case Graphic3d_TOLS_POSITIONAL:
-          aLightsLoop = aLightsLoop + EOL"    pointLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
-          break;
-        case Graphic3d_TOLS_SPOT:
-          aLightsLoop = aLightsLoop + EOL"    spotLight (" + anIndex + ", theNormal, theView, aPoint, theIsFront);";
-          break;
+        isFirstInLoop = false;
+        aLightsLoop +=
+          EOL"      if (aType == OccLightType_Direct)"
+          EOL"      {"
+          EOL"        directionalLight (anIndex, theNormal, theView, theIsFront);"
+          EOL"      }";
+      }
+      if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
+      {
+        if (!isFirstInLoop)
+        {
+          aLightsLoop += EOL"      else ";
+        }
+        isFirstInLoop = false;
+        aLightsLoop +=
+          EOL"      if (aType == OccLightType_Point)"
+          EOL"      {"
+          EOL"        pointLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+          EOL"      }";
+      }
+      if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
+      {
+        if (!isFirstInLoop)
+        {
+          aLightsLoop += EOL"      else ";
+        }
+        isFirstInLoop = false;
+        aLightsLoop +=
+          EOL"      if (aType == OccLightType_Spot)"
+          EOL"      {"
+          EOL"        spotLight (anIndex, theNormal, theView, aPoint, theIsFront);"
+          EOL"      }";
       }
-      aLightsMap[aLightIter.Value().Type] += 1;
+      aLightsLoop += EOL"    }";
     }
-    theNbLights = anIndex;
-    const Standard_Integer aNbLoopLights = aLightsMap[Graphic3d_TOLS_DIRECTIONAL]
-                                         + aLightsMap[Graphic3d_TOLS_POSITIONAL]
-                                         + aLightsMap[Graphic3d_TOLS_SPOT];
-    if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] == 1
-     && aNbLoopLights == 1)
+    if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) == 1
+     && theNbLights == 1)
     {
       // use the version with hard-coded first index
       aLightsLoop = EOL"    directionalLightFirst(theNormal, theView, theIsFront);";
       aLightsFunc += THE_FUNC_directionalLightFirst;
     }
-    else if (aLightsMap[Graphic3d_TOLS_DIRECTIONAL] > 0)
+    else if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_DIRECTIONAL) > 0)
     {
       aLightsFunc += THE_FUNC_directionalLight;
     }
-    if (aLightsMap[Graphic3d_TOLS_POSITIONAL] > 0)
+    if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_POSITIONAL) > 0)
     {
       aLightsFunc += THE_FUNC_pointLight;
     }
-    if (aLightsMap[Graphic3d_TOLS_SPOT] > 0)
+    if (aLights->NbEnabledLightsOfType (Graphic3d_TOLS_SPOT) > 0)
     {
       aLightsFunc += THE_FUNC_spotLight;
     }
index 17add9f..b1b4900 100644 (file)
@@ -204,7 +204,7 @@ public:
   const OpenGl_LightSourceState& LightSourceState() const { return myLightSourceState; }
 
   //! Updates state of OCCT light sources.
-  Standard_EXPORT void UpdateLightSourceStateTo (const OpenGl_ListOfLight* theLights);
+  Standard_EXPORT void UpdateLightSourceStateTo (const Handle(Graphic3d_LightSet)& theLights);
 
   //! Invalidate state of OCCT light sources.
   Standard_EXPORT void UpdateLightSourceState();
index fa75066..2aeaf26 100755 (executable)
@@ -160,34 +160,6 @@ const OpenGl_Mat4& OpenGl_WorldViewState::WorldViewMatrixInverse() const
   return myWorldViewMatrixInverse;
 }
 
-// =======================================================================
-// function : OpenGl_LightSourceState
-// purpose  : Creates uninitialized state of light sources
-// =======================================================================
-OpenGl_LightSourceState::OpenGl_LightSourceState()
-: myLightSources (NULL)
-{
-  //
-}
-
-// =======================================================================
-// function : Set
-// purpose  : Sets new light sources
-// =======================================================================
-void OpenGl_LightSourceState::Set (const OpenGl_ListOfLight* theLightSources)
-{
-  myLightSources = theLightSources;
-}
-
-// =======================================================================
-// function : LightSources
-// purpose  : Returns current list of light sources
-// =======================================================================
-const OpenGl_ListOfLight* OpenGl_LightSourceState::LightSources() const
-{
-  return myLightSources;
-}
-
 // =======================================================================
 // function : OpenGl_ClippingState
 // purpose  : Creates new clipping state
index 786b27e..eaa5abe 100755 (executable)
@@ -17,8 +17,8 @@
 #define _OpenGl_State_HeaderFile
 
 #include <NCollection_List.hxx>
+#include <Graphic3d_LightSet.hxx>
 #include <OpenGl_Element.hxx>
-#include <OpenGl_Light.hxx>
 #include <OpenGl_Vec.hxx>
 
 //! Defines interface for OpenGL state.
@@ -122,17 +122,17 @@ class OpenGl_LightSourceState : public OpenGl_StateInterface
 public:
 
   //! Creates uninitialized state of light sources.
-  Standard_EXPORT OpenGl_LightSourceState();
+  OpenGl_LightSourceState() {}
 
   //! Sets new light sources.
-  Standard_EXPORT void Set (const OpenGl_ListOfLight* theLightSources);
+  void Set (const Handle(Graphic3d_LightSet)& theLightSources) { myLightSources = theLightSources; }
 
   //! Returns current list of light sources.
-  Standard_EXPORT const OpenGl_ListOfLight* LightSources() const;
+  const Handle(Graphic3d_LightSet)& LightSources() const { return myLightSources; }
 
 private:
 
-  const OpenGl_ListOfLight* myLightSources; //!< List of OCCT light sources
+  Handle(Graphic3d_LightSet) myLightSources; //!< List of OCCT light sources
 
 };
 
index 4518242..1735b1d 100644 (file)
@@ -62,6 +62,8 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myToShowGradTrihedron  (false),
   myZLayers        (Structure_MAX_PRIORITY - Structure_MIN_PRIORITY + 1),
   myStateCounter         (theCounter),
+  myCurrLightSourceState (theCounter->Increment()),
+  myLightsRevision       (0),
   myLastLightSourceState (0, 0),
 #if !defined(GL_ES_VERSION_2_0)
   myFboColorFormat       (GL_RGBA8),
@@ -98,15 +100,12 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
 {
   myWorkspace = new OpenGl_Workspace (this, NULL);
 
-  OpenGl_Light       aLight;
-  aLight.Type        = Graphic3d_TOLS_AMBIENT;
-  aLight.IsHeadlight = Standard_False;
-  aLight.Color.r()   = 1.;
-  aLight.Color.g()   = 1.;
-  aLight.Color.b()   = 1.;
-  myNoShadingLight.Append (aLight);
+  Handle(Graphic3d_CLight) aLight = new Graphic3d_CLight (Graphic3d_TOLS_AMBIENT);
+  aLight->SetHeadlight (false);
+  aLight->SetColor (Quantity_NOC_WHITE);
+  myNoShadingLight = new Graphic3d_LightSet();
+  myNoShadingLight->Add (aLight);
 
-  myCurrLightSourceState     = myStateCounter->Increment();
   myMainSceneFbos[0]         = new OpenGl_FrameBuffer();
   myMainSceneFbos[1]         = new OpenGl_FrameBuffer();
   myMainSceneFbosOit[0]      = new OpenGl_FrameBuffer();
index f9e0142..200f34b 100644 (file)
@@ -42,7 +42,6 @@
 #include <OpenGl_FrameBuffer.hxx>
 #include <OpenGl_GraduatedTrihedron.hxx>
 #include <OpenGl_LayerList.hxx>
-#include <OpenGl_Light.hxx>
 #include <OpenGl_LineAttributes.hxx>
 #include <OpenGl_SceneGeometry.hxx>
 #include <OpenGl_Structure.hxx>
@@ -280,10 +279,10 @@ public:
   Standard_EXPORT virtual void SetCamera (const Handle(Graphic3d_Camera)& theCamera) Standard_OVERRIDE;
 
   //! Returns list of lights of the view.
-  virtual const Graphic3d_ListOfCLight& Lights() const Standard_OVERRIDE { return myLights; }
+  virtual const Handle(Graphic3d_LightSet)& Lights() const Standard_OVERRIDE { return myLights; }
 
   //! Sets list of lights for the view.
-  virtual void SetLights (const Graphic3d_ListOfCLight& theLights) Standard_OVERRIDE
+  virtual void SetLights (const Handle(Graphic3d_LightSet)& theLights) Standard_OVERRIDE
   {
     myLights = theLights;
     myCurrLightSourceState = myStateCounter->Increment();
@@ -325,9 +324,6 @@ public:
   //! Returns list of OpenGL Z-layers.
   const OpenGl_LayerList& LayerList() const { return myZLayers; }
 
-  //! Returns list of openGL light sources.
-  const OpenGl_ListOfLight& LightList() const { return myLights; }
-
   //! Returns OpenGL window implementation.
   const Handle(OpenGl_Window) GlWindow() const { return myWindow; }
 
@@ -484,13 +480,14 @@ protected:
   Handle(Graphic3d_TextureEnv)    myTextureEnvData;
   Graphic3d_GraduatedTrihedron    myGTrihedronData;
 
-  OpenGl_ListOfLight              myNoShadingLight;
-  OpenGl_ListOfLight              myLights;
+  Handle(Graphic3d_LightSet)      myNoShadingLight;
+  Handle(Graphic3d_LightSet)      myLights;
   OpenGl_LayerList                myZLayers; //!< main list of displayed structure, sorted by layers
 
   Graphic3d_WorldViewProjState    myWorldViewProjState; //!< camera modification state
   OpenGl_StateCounter*            myStateCounter;
   Standard_Size                   myCurrLightSourceState;
+  Standard_Size                   myLightsRevision;
 
   typedef std::pair<Standard_Size, Standard_Size> StateInfo;
 
index 04fcc20..c8340b8 100644 (file)
@@ -42,24 +42,6 @@ namespace
 {
   static const OpenGl_Vec4 THE_WHITE_COLOR (1.0f, 1.0f, 1.0f, 1.0f);
   static const OpenGl_Vec4 THE_BLACK_COLOR (0.0f, 0.0f, 0.0f, 1.0f);
-
-  //! Operator returning TRUE for positional light sources.
-  struct IsLightPositional
-  {
-    bool operator() (const OpenGl_Light& theLight)
-    {
-      return theLight.Type != Graphic3d_TOLS_DIRECTIONAL;
-    }
-  };
-
-  //! Operator returning TRUE for any non-ambient light sources.
-  struct IsNotAmbient
-  {
-    bool operator() (const OpenGl_Light& theLight)
-    {
-      return theLight.Type != Graphic3d_TOLS_AMBIENT;
-    }
-  };
 }
 
 namespace
@@ -2491,68 +2473,75 @@ Standard_Boolean OpenGl_View::uploadRaytraceData (const Handle(OpenGl_Context)&
 // =======================================================================
 Standard_Boolean OpenGl_View::updateRaytraceLightSources (const OpenGl_Mat4& theInvModelView, const Handle(OpenGl_Context)& theGlContext)
 {
-  std::vector<OpenGl_Light> aLightSources;
-
-  if (myShadingModel != Graphic3d_TOSM_NONE)
+  std::vector<Handle(Graphic3d_CLight)> aLightSources;
+  myRaytraceGeometry.Ambient = BVH_Vec4f (0.f, 0.f, 0.f, 0.f);
+  if (myShadingModel != Graphic3d_TOSM_NONE
+  && !myLights.IsNull())
   {
-    aLightSources.assign (myLights.begin(), myLights.end());
+    const Graphic3d_Vec4& anAmbient = myLights->AmbientColor();
+    myRaytraceGeometry.Ambient = BVH_Vec4f (anAmbient.r(), anAmbient.g(), anAmbient.b(), 0.0f);
 
     // move positional light sources at the front of the list
-    std::partition (aLightSources.begin(), aLightSources.end(), IsLightPositional());
+    aLightSources.reserve (myLights->Extent());
+    for (Graphic3d_LightSet::Iterator aLightIter (myLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
+         aLightIter.More(); aLightIter.Next())
+    {
+      const Graphic3d_CLight& aLight = *aLightIter.Value();
+      if (aLight.Type() != Graphic3d_TOLS_DIRECTIONAL)
+      {
+        aLightSources.push_back (aLightIter.Value());
+      }
+    }
+
+    for (Graphic3d_LightSet::Iterator aLightIter (myLights, Graphic3d_LightSet::IterationFilter_ExcludeDisabledAndAmbient);
+         aLightIter.More(); aLightIter.Next())
+    {
+      if (aLightIter.Value()->Type() == Graphic3d_TOLS_DIRECTIONAL)
+      {
+        aLightSources.push_back (aLightIter.Value());
+      }
+    }
   }
 
   // get number of 'real' (not ambient) light sources
-  const size_t aNbLights = std::count_if (aLightSources.begin(), aLightSources.end(), IsNotAmbient());
-
+  const size_t aNbLights = aLightSources.size();
   Standard_Boolean wasUpdated = myRaytraceGeometry.Sources.size () != aNbLights;
-
   if (wasUpdated)
   {
     myRaytraceGeometry.Sources.resize (aNbLights);
   }
 
-  myRaytraceGeometry.Ambient = BVH_Vec4f (0.f, 0.f, 0.f, 0.f);
-
   for (size_t aLightIdx = 0, aRealIdx = 0; aLightIdx < aLightSources.size(); ++aLightIdx)
   {
-    const OpenGl_Light& aLight = aLightSources[aLightIdx];
-
-    if (aLight.Type == Graphic3d_TOLS_AMBIENT)
-    {
-      myRaytraceGeometry.Ambient += BVH_Vec4f (aLight.Color.r() * aLight.Intensity,
-                                               aLight.Color.g() * aLight.Intensity,
-                                               aLight.Color.b() * aLight.Intensity,
-                                               0.0f);
-      continue;
-    }
-
-    BVH_Vec4f aEmission  (aLight.Color.r() * aLight.Intensity,
-                          aLight.Color.g() * aLight.Intensity,
-                          aLight.Color.b() * aLight.Intensity,
+    const Graphic3d_CLight& aLight = *aLightSources[aLightIdx];
+    const Graphic3d_Vec4& aLightColor = aLight.PackedColor();
+    BVH_Vec4f aEmission  (aLightColor.r() * aLight.Intensity(),
+                          aLightColor.g() * aLight.Intensity(),
+                          aLightColor.b() * aLight.Intensity(),
                           1.0f);
 
-    BVH_Vec4f aPosition (-aLight.Direction.x(),
-                         -aLight.Direction.y(),
-                         -aLight.Direction.z(),
+    BVH_Vec4f aPosition (-aLight.PackedDirection().x(),
+                         -aLight.PackedDirection().y(),
+                         -aLight.PackedDirection().z(),
                          0.0f);
 
-    if (aLight.Type != Graphic3d_TOLS_DIRECTIONAL)
+    if (aLight.Type() != Graphic3d_TOLS_DIRECTIONAL)
     {
-      aPosition = BVH_Vec4f (static_cast<float>(aLight.Position.x()),
-                             static_cast<float>(aLight.Position.y()),
-                             static_cast<float>(aLight.Position.z()),
+      aPosition = BVH_Vec4f (static_cast<float>(aLight.Position().X()),
+                             static_cast<float>(aLight.Position().Y()),
+                             static_cast<float>(aLight.Position().Z()),
                              1.0f);
 
       // store smoothing radius in W-component
-      aEmission.w() = Max (aLight.Smoothness, 0.f);
+      aEmission.w() = Max (aLight.Smoothness(), 0.f);
     }
     else
     {
       // store cosine of smoothing angle in W-component
-      aEmission.w() = cosf (Min (Max (aLight.Smoothness, 0.f), static_cast<Standard_ShortReal> (M_PI / 2.0)));
+      aEmission.w() = cosf (Min (Max (aLight.Smoothness(), 0.f), static_cast<Standard_ShortReal> (M_PI / 2.0)));
     }
 
-    if (aLight.IsHeadlight)
+    if (aLight.IsHeadlight())
     {
       aPosition = theInvModelView * aPosition;
     }
index bc36fcc..9899c81 100644 (file)
@@ -883,10 +883,18 @@ void OpenGl_View::render (Graphic3d_Camera::Projection theProjection,
   myBVHSelector.SetViewportSize (myWindow->Width(), myWindow->Height(), myRenderParams.ResolutionRatio());
   myBVHSelector.CacheClipPtsProjections();
 
-  const Handle(OpenGl_ShaderManager)& aManager   = aContext->ShaderManager();
-  if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState)
+  const Handle(OpenGl_ShaderManager)& aManager = aContext->ShaderManager();
+  const Handle(Graphic3d_LightSet)&   aLights  = myShadingModel == Graphic3d_TOSM_NONE ? myNoShadingLight : myLights;
+  Standard_Size aLightsRevision = 0;
+  if (!aLights.IsNull())
   {
-    aManager->UpdateLightSourceStateTo (myShadingModel == Graphic3d_TOSM_NONE ? &myNoShadingLight : &myLights);
+    aLightsRevision = aLights->UpdateRevision();
+  }
+  if (StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index()) != myLastLightSourceState
+   || aLightsRevision != myLightsRevision)
+  {
+    myLightsRevision = aLightsRevision;
+    aManager->UpdateLightSourceStateTo (aLights);
     myLastLightSourceState = StateInfo (myCurrLightSourceState, aManager->LightSourceState().Index());
   }
 
index 536c2c2..4d93e57 100644 (file)
@@ -24,7 +24,6 @@
 #include <Graphic3d_ArrayOfPolylines.hxx>
 #include <Graphic3d_ArrayOfSegments.hxx>
 #include <Graphic3d_Group.hxx>
-#include <Graphic3d_Vertex.hxx>
 #include <Prs3d.hxx>
 #include <Prs3d_Arrow.hxx>
 #include <Prs3d_ArrowAspect.hxx>
index 13db126..bb363aa 100755 (executable)
@@ -9,7 +9,6 @@ V3d_Coordinate.hxx
 V3d_DirectionalLight.cxx
 V3d_DirectionalLight.hxx
 V3d_ImageDumpOptions.hxx
-V3d_Light.cxx
 V3d_Light.hxx
 V3d_ListOfLight.hxx
 V3d_ListOfView.hxx
index 79d89c7..2e92a00 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// Modified     23/02/98 : FMN ; Remplacement PI par Standard_PI
-//              02.15.100 : JR : Clutter
-//-Version
-//-Design       
-//-Warning     
-//-References
-//-Language     C++ 2.1
-//-Declarations
-// for the class
+#include <V3d.hxx>
 
 #include <Aspect_Grid.hxx>
 #include <Aspect_Window.hxx>
@@ -31,7 +23,6 @@
 #include <Graphic3d_Group.hxx>
 #include <Graphic3d_Structure.hxx>
 #include <Quantity_NameOfColor.hxx>
-#include <V3d.hxx>
 #include <V3d_View.hxx>
 #include <V3d_Viewer.hxx>
 
index 0d22795..07672ea 100644 (file)
 #ifndef _V3d_HeaderFile
 #define _V3d_HeaderFile
 
+#include <gp_Dir.hxx>
 #include <Standard.hxx>
 #include <Standard_DefineAlloc.hxx>
 #include <Standard_Handle.hxx>
-
-#include <V3d_TypeOfOrientation.hxx>
 #include <Standard_Real.hxx>
+#include <V3d_TypeOfOrientation.hxx>
 
+class Graphic3d_Group;
 class V3d_View;
 
 //! This package contains the set of commands and services
index 7617114..3dc9986 100644 (file)
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// Modified     30-03-98 : ZOV ; PRO6774 (reconstruction of the class hierarchy and suppressing useless methods)
-
 #include <V3d_AmbientLight.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light)
+#include <V3d_Viewer.hxx>
+
+IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight, Graphic3d_CLight)
+
+// =======================================================================
+// function : V3d_AmbientLight
+// purpose  :
+// =======================================================================
+V3d_AmbientLight::V3d_AmbientLight (const Quantity_Color& theColor)
+: Graphic3d_CLight (Graphic3d_TOLS_AMBIENT)
+{
+  SetColor (theColor);
+}
 
 // =======================================================================
 // function : V3d_AmbientLight
@@ -25,8 +35,11 @@ IMPLEMENT_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light)
 // =======================================================================
 V3d_AmbientLight::V3d_AmbientLight (const Handle(V3d_Viewer)& theViewer,
                                     const Quantity_Color& theColor)
-: V3d_Light (theViewer)
+: Graphic3d_CLight (Graphic3d_TOLS_AMBIENT)
 {
-  SetType  (V3d_AMBIENT);
   SetColor (theColor);
+  if (!theViewer.IsNull())
+  {
+    theViewer->AddLight (this);
+  }
 }
index 72451ec..eccc5a0 100644 (file)
 #include <V3d_Light.hxx>
 
 class V3d_Viewer;
-class V3d_AmbientLight;
-DEFINE_STANDARD_HANDLE(V3d_AmbientLight, V3d_Light)
 
 //! Creation of an ambient light source in a viewer.
-class V3d_AmbientLight : public V3d_Light
+class V3d_AmbientLight : public Graphic3d_CLight
 {
-
+  DEFINE_STANDARD_RTTIEXT(V3d_AmbientLight, Graphic3d_CLight)
 public:
 
   //! Constructs an ambient light source in the viewer.
   //! The default Color of this light source is WHITE.
+  Standard_EXPORT V3d_AmbientLight (const Quantity_Color& theColor = Quantity_NOC_WHITE);
+
+  //! Constructs an ambient light source in the viewer.
+  //! The default Color of this light source is WHITE.
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_AmbientLight (const Handle(V3d_Viewer)& theViewer,
                                     const Quantity_Color& theColor = Quantity_NOC_WHITE);
 
-  DEFINE_STANDARD_RTTIEXT(V3d_AmbientLight,V3d_Light)
+//! @name hidden properties not applicable to ambient light
+private:
+
+  using Graphic3d_CLight::IsHeadlight;
+  using Graphic3d_CLight::Headlight;
+  using Graphic3d_CLight::SetHeadlight;
+  using Graphic3d_CLight::Position;
+  using Graphic3d_CLight::SetPosition;
+  using Graphic3d_CLight::ConstAttenuation;
+  using Graphic3d_CLight::LinearAttenuation;
+  using Graphic3d_CLight::Attenuation;
+  using Graphic3d_CLight::SetAttenuation;
+  using Graphic3d_CLight::Direction;
+  using Graphic3d_CLight::SetDirection;
+  using Graphic3d_CLight::Angle;
+  using Graphic3d_CLight::SetAngle;
+  using Graphic3d_CLight::Concentration;
+  using Graphic3d_CLight::SetConcentration;
+  using Graphic3d_CLight::Smoothness;
+  using Graphic3d_CLight::SetSmoothRadius;
+  using Graphic3d_CLight::SetSmoothAngle;
+
 };
 
+DEFINE_STANDARD_HANDLE(V3d_AmbientLight, Graphic3d_CLight)
+
 #endif // _V3d_AmbientLight_HeaderFile
index c7ba041..69aac38 100644 (file)
 
 #include <V3d_DirectionalLight.hxx>
 
-#include <Graphic3d_ArrayOfSegments.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_Group.hxx>
-#include <Graphic3d_Structure.hxx>
-#include <TColStd_Array2OfReal.hxx>
 #include <V3d.hxx>
-#include <V3d_BadValue.hxx>
-#include <V3d_View.hxx>
-#include <V3d_Viewer.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(V3d_DirectionalLight,V3d_PositionLight)
 
@@ -29,269 +21,70 @@ IMPLEMENT_STANDARD_RTTIEXT(V3d_DirectionalLight,V3d_PositionLight)
 // function : V3d_DirectionalLight
 // purpose  :
 // =======================================================================
-V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
-                                            const V3d_TypeOfOrientation theDirection,
+V3d_DirectionalLight::V3d_DirectionalLight (const V3d_TypeOfOrientation theDirection,
                                             const Quantity_Color& theColor,
                                             const Standard_Boolean theIsHeadlight)
-: V3d_PositionLight (theViewer)
+: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, Handle(V3d_Viewer)())
 {
-  gp_Dir aV = V3d::GetProjAxis (theDirection);
-  SetType (V3d_DIRECTIONAL);
   SetColor (theColor);
   SetHeadlight (theIsHeadlight);
-  SetTarget (0., 0., 0.);
-  SetPosition (-aV.X(), -aV.Y(), -aV.Z());
-  SetSmoothAngle (0.2);
-  SetIntensity (20.0);
+  SetDirection (V3d::GetProjAxis (theDirection));
 }
 
 // =======================================================================
 // function : V3d_DirectionalLight
 // purpose  :
 // =======================================================================
-V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
-                                            const Standard_Real theXt,
-                                            const Standard_Real theYt,
-                                            const Standard_Real theZt,
-                                            const Standard_Real theXp,
-                                            const Standard_Real theYp,
-                                            const Standard_Real theZp,
+V3d_DirectionalLight::V3d_DirectionalLight (const gp_Dir& theDirection,
                                             const Quantity_Color& theColor,
                                             const Standard_Boolean theIsHeadlight)
-: V3d_PositionLight (theViewer)
+: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, Handle(V3d_Viewer)())
 {
-  SetType (V3d_DIRECTIONAL);
   SetColor (theColor);
   SetHeadlight (theIsHeadlight);
-  SetTarget (theXt, theYt, theZt);
-  SetPosition (theXp, theYp, theZp);
+  SetDirection (theDirection);
 }
 
 // =======================================================================
-// function : SetSmoothAngle
+// function : V3d_DirectionalLight
 // purpose  :
 // =======================================================================
-void V3d_DirectionalLight::SetSmoothAngle (const Standard_Real theValue)
+V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
+                                            const V3d_TypeOfOrientation theDirection,
+                                            const Quantity_Color& theColor,
+                                            const Standard_Boolean theIsHeadlight)
+: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, theViewer)
 {
-  V3d_BadValue_Raise_if (theValue < 0.0 || theValue > M_PI / 2.0,
-    "Bad value for smoothing angle");
-
-  myLight.Smoothness = static_cast<Standard_ShortReal> (theValue);
+  SetColor (theColor);
+  SetHeadlight (theIsHeadlight);
+  SetDirection (V3d::GetProjAxis (theDirection));
 }
 
 // =======================================================================
-// function : SetDirection
+// function : V3d_DirectionalLight
 // purpose  :
 // =======================================================================
-void V3d_DirectionalLight::SetDirection (V3d_TypeOfOrientation theDirection)
+V3d_DirectionalLight::V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
+                                            const Standard_Real theXt,
+                                            const Standard_Real theYt,
+                                            const Standard_Real theZt,
+                                            const Standard_Real theXp,
+                                            const Standard_Real theYp,
+                                            const Standard_Real theZp,
+                                            const Quantity_Color& theColor,
+                                            const Standard_Boolean theIsHeadlight)
+: V3d_PositionLight (Graphic3d_TOLS_DIRECTIONAL, theViewer)
 {
-  gp_Dir aV = V3d::GetProjAxis (theDirection);
-  SetDirection (aV.X(), aV.Y(), aV.Z());
+  SetColor (theColor);
+  SetHeadlight (theIsHeadlight);
+  SetDirection (gp_Dir (gp_XYZ (theXt, theYt, theZt) - gp_XYZ(theXp, theYp, theZp)));
 }
 
 // =======================================================================
 // function : SetDirection
 // purpose  :
 // =======================================================================
-void V3d_DirectionalLight::SetDirection (Standard_Real theVx,
-                                         Standard_Real theVy,
-                                         Standard_Real theVz)
-{
-  gp_Dir aV (theVx, theVy, theVz);
-  myLight.Direction.x() = static_cast<Standard_ShortReal> (aV.X());
-  myLight.Direction.y() = static_cast<Standard_ShortReal> (aV.Y());
-  myLight.Direction.z() = static_cast<Standard_ShortReal> (aV.Z());
-}
-
-// =======================================================================
-// function : SetDisplayPosition
-// purpose  :
-// =======================================================================
-void V3d_DirectionalLight::SetDisplayPosition (Standard_Real theX,
-                                               Standard_Real theY,
-                                               Standard_Real theZ)
-{
-  myDisplayPosition.SetCoord(theX, theY, theZ);
-
-  gp_XYZ aTarget;
-  Target (aTarget.ChangeCoord (1), aTarget.ChangeCoord (2), aTarget.ChangeCoord (3));
-
-  const gp_XYZ aDispPos = aTarget - gp_XYZ(theX, theY, theZ);
-  if (aDispPos.Modulus() > gp::Resolution())
-  {
-    SetDirection (aDispPos.X(), aDispPos.Y(), aDispPos.Z());
-  }
-}
-
-// =======================================================================
-// function : DisplayPosition
-// purpose  :
-// =======================================================================
-void V3d_DirectionalLight::Symbol (const Handle(Graphic3d_Group)& theSymbol, const Handle(V3d_View)& theView) const
-{
-  Standard_Real Xi,Yi,Zi,Xf,Yf,Zf,Rayon,PXT,PYT,X,Y,Z,XT,YT,ZT;
-  Standard_Real A,B,C,Dist,Beta,CosBeta,SinBeta,Coef,X1,Y1,Z1;
-  Standard_Real DX,DY,DZ,VX,VY,VZ;
-  Standard_Integer IXP,IYP,j;
-  TColStd_Array2OfReal MatRot(0,2,0,2);
-
-  theView->Proj(VX,VY,VZ);
-  this->DisplayPosition(Xi,Yi,Zi);
-  Rayon = this->Radius();
-  theView->Project(Xi,Yi,Zi,PXT,PYT); 
-  theView->Convert(PXT,PYT,IXP,IYP);
-//  Coordinated 3d in the plane of projection of the source.
-  theView->Convert(IXP,IYP,XT,YT,ZT);
-  theView->Convert(PXT,PYT+Rayon,IXP,IYP);
-  theView->Convert(IXP,IYP,X,Y,Z);
-  X = X+Xi-XT; Y = Y+Yi-YT; Z = Z+Zi-ZT;
-  Dist = Sqrt( Square(X-Xi) + Square(Y-Yi) + Square(Z-Zi) );
-//  Axis of rotation.
-  A = (X-Xi)/Dist;
-  B = (Y-Yi)/Dist;
-  C = (Z-Zi)/Dist;
-
-//  A sphere is drawn
-  V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
-  for( j=1 ; j<=3 ; j++ ) {
-    Beta = j * M_PI / 4.;
-    CosBeta = Cos(Beta);
-    SinBeta = Sin(Beta);
-    Coef = 1. - CosBeta;
-    MatRot(0,0) =  A * A + (1. - A * A) * CosBeta;
-    MatRot(0,1) = -C * SinBeta + Coef * A * B;
-    MatRot(0,2) =  B * SinBeta + Coef * A * C;
-    MatRot(1,0) =  C * SinBeta + Coef * A * B; 
-    MatRot(1,1) =  B * B + (1. - B * B) * CosBeta;
-    MatRot(1,2) = -A * SinBeta + Coef * B * C;
-    MatRot(2,0) = -B * SinBeta + Coef * A * C;
-    MatRot(2,1) =  A * SinBeta + Coef * B * C;
-    MatRot(2,2) =  C * C + (1. - C * C) * CosBeta;
-    Xf = Xi * MatRot(0,0) + Yi * MatRot(0,1) + Zi * MatRot(0,2);
-    Yf = Xi * MatRot(1,0) + Yi * MatRot(1,1) + Zi * MatRot(1,2);
-    Zf = Xi * MatRot(2,0) + Yi * MatRot(2,1) + Zi * MatRot(2,2);
-//    Rotation of the normal
-    X1 = VX * MatRot(0,0) + VY * MatRot(0,1) + VZ * MatRot(0,2);
-    Y1 = VX * MatRot(1,0) + VY * MatRot(1,1) + VZ * MatRot(1,2);
-    Z1 = VX * MatRot(2,0) + VY * MatRot(2,1) + VZ * MatRot(2,2);
-    VX = X1 + Xi - Xf ; VY = Y1 + Yi - Yf ; VZ = Z1 + Zi - Zf;
-    V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
-  }
-
-//  The arrow is drawn
-  Rayon = this->Radius();
-  this->Direction(DX,DY,DZ);
-  X = Xi + DX*Rayon/10.; Y = Yi + DY*Rayon/10.; Z = Zi + DZ*Rayon/10.;
-
-  Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
-  aPrims->AddVertex(Standard_ShortReal(Xi),Standard_ShortReal(Yi),Standard_ShortReal(Zi));
-  aPrims->AddVertex(Standard_ShortReal(X),Standard_ShortReal(Y),Standard_ShortReal(Z));
-  theSymbol->AddPrimitiveArray(aPrims);
-
-  V3d::ArrowOfRadius(theSymbol, X, Y, Z, DX, DY, DZ, M_PI / 15., Rayon / 20.);
-}
-
-// =======================================================================
-// function : Display
-// purpose  :
-// =======================================================================
-void V3d_DirectionalLight::Display (const Handle(V3d_View)& theView,
-                                    const V3d_TypeOfRepresentation theTPres)
+void V3d_DirectionalLight::SetDirection (V3d_TypeOfOrientation theDirection)
 {
-  Standard_Real X,Y,Z,Rayon;
-  Standard_Real X0,Y0,Z0,VX,VY,VZ;
-  Standard_Real X1,Y1,Z1;
-  Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
-  V3d_TypeOfRepresentation Pres;
-
-//  Creation of a structure of markable elements (position of the
-//  light, and the domain of lighting represented by a circle)
-//  Creation of a structure of non-markable elements (target, meridian and 
-//  parallel).
-
-    Pres = theTPres;
-    Handle(V3d_Viewer) TheViewer = theView->Viewer();
-    if (!myGraphicStructure.IsNull()) {
-       myGraphicStructure->Disconnect(myGraphicStructure1);
-       myGraphicStructure->Clear();
-       myGraphicStructure1->Clear();
-       if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation;
-    }
-    else {
-      if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
-      Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager());
-      myGraphicStructure = slight;
-      Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); 
-      myGraphicStructure1 = snopick;
-    }
-  
-  Handle(Graphic3d_Group) glight  = myGraphicStructure->NewGroup();
-  Handle(Graphic3d_Group) gsphere;
-  if (Pres == V3d_COMPLETE
-   || Pres == V3d_PARTIAL)
-  {
-    gsphere = myGraphicStructure->NewGroup();
-  }
-  
-  Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup();
-  
-  X0 = myTarget.X();
-  Y0 = myTarget.Y();
-  Z0 = myTarget.Z();
-
-//Display of the position of the light.
-
-  const Quantity_Color Col1 = this->Color();
-  Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
-  Asp1->SetColor(Col1);
-  glight->SetPrimitivesAspect(Asp1);
-  this->Symbol(glight,theView);
-  
-  // Display of the markable sphere (limit at the circle).
-
-  if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
-    
-    Rayon = this->Radius(); 
-    theView->Proj(VX,VY,VZ);
-    V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
-    
-//Display of the meridian
-
-    Quantity_Color Col2(Quantity_NOC_GREEN);
-    Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d
-      (Col2,Aspect_TOL_SOLID,1.);
-    gnopick->SetPrimitivesAspect(Asp2);
-    
-//    Definition of the axis of circle
-    theView->Up(DXRef,DYRef,DZRef);
-    this->DisplayPosition(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-      
-//  Display of the parallel
-
-//    Definition of the axis of circle
-    theView->Proj(VX,VY,VZ);
-    theView->Up(X1,Y1,Z1);
-    DXRef = VY * Z1 - VZ * Y1;
-    DYRef = VZ * X1 - VX * Z1;
-    DZRef = VX * Y1 - VY * X1;
-    this->DisplayPosition(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-    
-  }
-  
-  myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT);
-//    cout << "MyGraphicStructure exploration \n" << flush; MyGraphicStructure->Exploration();
-  myTypeOfRepresentation = Pres;
-  myGraphicStructure->Display();
+  SetDirection (V3d::GetProjAxis (theDirection));
 }
index 435de08..30215cc 100644 (file)
 #include <V3d_PositionLight.hxx>
 #include <V3d_TypeOfOrientation.hxx>
 
-class V3d_Viewer;
-class V3d_DirectionalLight;
-DEFINE_STANDARD_HANDLE(V3d_DirectionalLight, V3d_PositionLight)
-
 //! Directional light source for a viewer.
 class V3d_DirectionalLight : public V3d_PositionLight
 {
+  DEFINE_STANDARD_RTTIEXT(V3d_DirectionalLight, V3d_PositionLight)
 public:
 
   //! Creates a directional light source in the viewer.
+  Standard_EXPORT V3d_DirectionalLight (const V3d_TypeOfOrientation theDirection = V3d_XposYposZpos,
+                                        const Quantity_Color& theColor = Quantity_NOC_WHITE,
+                                        const Standard_Boolean theIsHeadlight = Standard_False);
+
+  //! Creates a directional light source in the viewer.
+  Standard_EXPORT V3d_DirectionalLight (const gp_Dir& theDirection,
+                                        const Quantity_Color& theColor = Quantity_NOC_WHITE,
+                                        const Standard_Boolean theIsHeadlight = Standard_False);
+
+  //! Defines the direction of the light source by a predefined orientation.
+  Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theDirection);
+  using Graphic3d_CLight::SetDirection;
+
+public:
+
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
                                         const V3d_TypeOfOrientation theDirection = V3d_XposYposZpos,
                                         const Quantity_Color& theColor = Quantity_NOC_WHITE,
@@ -39,6 +52,7 @@ public:
   //! theXt, theYt, theZt : Coordinate of light source Target.
   //! theXp, theYp, theZp : Coordinate of light source Position.
   //! The others parameters describe before.
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_DirectionalLight (const Handle(V3d_Viewer)& theViewer,
                                         const Standard_Real theXt,
                                         const Standard_Real theYt,
@@ -49,71 +63,22 @@ public:
                                         const Quantity_Color& theColor = Quantity_NOC_WHITE,
                                         const Standard_Boolean theIsHeadlight = Standard_False);
 
-  //! Defines the direction of the light source by a predefined orientation.
-  Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theDirection);
-
-  //! Defines the direction of the light source by the predefined vector theXm, theYm, theZm.
-  //! Warning: raises  BadValue from V3d if the vector is null.
-  Standard_EXPORT void SetDirection (Standard_Real theXm,
-                                     Standard_Real theYm,
-                                     Standard_Real theZm);
-
-  //! Defines the point of light source representation.
-  Standard_EXPORT void SetDisplayPosition (Standard_Real theX,
-                                           Standard_Real theY,
-                                           Standard_Real theZ);
-
-  //! Calls SetDisplayPosition method.
-  virtual void SetPosition (Standard_Real theXp,
-                            Standard_Real theYp,
-                            Standard_Real theZp) Standard_OVERRIDE { SetDisplayPosition (theXp, theYp, theZp); }
-
-  //! Modifies the smoothing angle (in radians)
-  Standard_EXPORT void SetSmoothAngle (const Standard_Real theValue);
-
-  //! Display the graphic structure of light source
-  //! in the chosen view. We have three type of representation
-  //! - SIMPLE   : Only the light source is displayed.
-  //! - PARTIAL  : The light source and the light space are
-  //! displayed.
-  //! - COMPLETE : The same representation as PARTIAL.
-  //! We can choose the "SAMELAST" as parameter of representation
-  //! In this case the graphic structure representation will be
-  //! the last displayed.
-  Standard_EXPORT void Display (const Handle(V3d_View)& theView,
-                                const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE;
-
-  //! Calls DisplayPosition method.
-  virtual void Position (Standard_Real& theX,
-                         Standard_Real& theY,
-                         Standard_Real& theZ) const Standard_OVERRIDE { DisplayPosition (theX, theY, theZ); }
-
-  //! Returns the chosen position to represent the light source.
-  void DisplayPosition (Standard_Real& theX,
-                        Standard_Real& theY,
-                        Standard_Real& theZ) const { myDisplayPosition.Coord (theX, theY, theZ); }
-
-  //! Returns the theVx, theVy, theVz direction of the light source.
-  void Direction (Standard_Real& theVx,
-                  Standard_Real& theVy,
-                  Standard_Real& theVz) const
-  {
-    theVx = myLight.Direction.x();
-    theVy = myLight.Direction.y();
-    theVz = myLight.Direction.z();
-  }
-
-  DEFINE_STANDARD_RTTIEXT(V3d_DirectionalLight,V3d_PositionLight)
-
+//! @name hidden properties not applicable to directional light
 private:
 
-  //! Defines the representation of the directional light source.
-  Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol,
-                               const Handle(V3d_View)& theView) const Standard_OVERRIDE;
+  using Graphic3d_CLight::Position;
+  using Graphic3d_CLight::SetPosition;
+  using Graphic3d_CLight::ConstAttenuation;
+  using Graphic3d_CLight::LinearAttenuation;
+  using Graphic3d_CLight::Attenuation;
+  using Graphic3d_CLight::SetAttenuation;
+  using Graphic3d_CLight::Angle;
+  using Graphic3d_CLight::SetAngle;
+  using Graphic3d_CLight::Concentration;
+  using Graphic3d_CLight::SetConcentration;
 
-private:
-
-  gp_Pnt myDisplayPosition;
 };
 
+DEFINE_STANDARD_HANDLE(V3d_DirectionalLight, V3d_PositionLight)
+
 #endif // _V3d_DirectionalLight_HeaderFile
diff --git a/src/V3d/V3d_Light.cxx b/src/V3d/V3d_Light.cxx
deleted file mode 100644 (file)
index b4ac19a..0000000
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright (c) 1999-2014 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.
-
-/***********************************************************************
-     FONCTION :
-     ----------
-        Classe V3d_SpotLight :
-     HISTORIQUE DES MODIFICATIONS   :
-     --------------------------------
-      00-09-92 : GG  ; Creation.
-************************************************************************/
-/*----------------------------------------------------------------------*/
-/*
- * Includes
- */
-
-#include <Graphic3d_Structure.hxx>
-#include <Quantity_Color.hxx>
-#include <Standard_Type.hxx>
-#include <V3d.hxx>
-#include <V3d_BadValue.hxx>
-#include <V3d_Light.hxx>
-#include <V3d_View.hxx>
-#include <V3d_Viewer.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(V3d_Light,Standard_Transient)
-
-// =======================================================================
-// function : V3d_Light
-// purpose  :
-// =======================================================================
-V3d_Light::V3d_Light (const Handle(V3d_Viewer)& theViewer)
-{
-  SetType (V3d_AMBIENT);
-  theViewer->AddLight (this);
-}
-
-// =======================================================================
-// function : SetType
-// purpose  :
-// =======================================================================
-void V3d_Light::SetType (const V3d_TypeOfLight theType)
-{
-  myLight.Type = (Graphic3d_TypeOfLightSource)theType;
-}
-
-// =======================================================================
-// function : SetColor
-// purpose  :
-// =======================================================================
-void V3d_Light::SetColor (const Quantity_Color& theColor)
-{
-  myLight.Color.r() = static_cast<Standard_ShortReal> (theColor.Red());
-  myLight.Color.g() = static_cast<Standard_ShortReal> (theColor.Green());
-  myLight.Color.b() = static_cast<Standard_ShortReal> (theColor.Blue());
-}
-
-// =======================================================================
-// function : Type
-// purpose  :
-// =======================================================================
-V3d_TypeOfLight V3d_Light::Type() const
-{
-  return (V3d_TypeOfLight)myLight.Type;
-}
-
-// =======================================================================
-// function : SetIntensity
-// purpose  :
-// =======================================================================
-void V3d_Light::SetIntensity (const Standard_Real theValue)
-{
-  Standard_ASSERT_RAISE (theValue > 0.,
-                         "V3d_Light::SetIntensity, "
-                         "Negative value for intensity");
-
-  myLight.Intensity = static_cast<Standard_ShortReal> (theValue);
-}
-
-// =======================================================================
-// function : Intensity
-// purpose  :
-// =======================================================================
-Standard_Real V3d_Light::Intensity() const
-{
-  return myLight.Intensity;
-}
-
-// =======================================================================
-// function : Smoothness
-// purpose  :
-// =======================================================================
-Standard_Real V3d_Light::Smoothness() const
-{
-  return myLight.Smoothness;
-}
-
-// =======================================================================
-// function : Headlight
-// purpose  :
-// =======================================================================
-Standard_Boolean V3d_Light::Headlight() const
-{
-  return myLight.IsHeadlight;
-}
-
-// =======================================================================
-// function : SetHeadlight
-// purpose  :
-// =======================================================================
-void V3d_Light::SetHeadlight (const Standard_Boolean theValue)
-{
-  myLight.IsHeadlight = theValue;
-}
-
-// =======================================================================
-// function : SymetricPointOnSphere
-// purpose  :
-// =======================================================================
-void V3d_Light::SymetricPointOnSphere (const Handle(V3d_View)& aView,
-                                       const gp_Pnt& Center,
-                                       const gp_Pnt& aPoint,
-                                       const Standard_Real Rayon,
-                                       Standard_Real& X, Standard_Real& Y, Standard_Real& Z,
-                                       Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ )
-{
-  Standard_Real X0,Y0,Z0,XP,YP,ZP;
-  Standard_Real PXP,PYP,DeltaX,DeltaY,DeltaZ;
-  Standard_Real A,B,C,Delta,Lambda;
-  Standard_Integer IPX,IPY;
-
-  Center.Coord(X0,Y0,Z0);
-  aPoint.Coord(XP,YP,ZP);
-  aView->Project(XP,YP,ZP,PXP,PYP);
-  aView->Convert(PXP,PYP,IPX,IPY);
-  aView->ProjReferenceAxe(IPX,IPY,X,Y,Z,VX,VY,VZ);
-  DeltaX = X0 - XP;
-  DeltaY = Y0 - YP;
-  DeltaZ = Z0 - ZP;
-
-//      The point of intersection of straight lines defined by :
-//      - Straight line passing by the point of projection and the eye
-//        if this is a perspective, parralel to the normal of the view 
-//        if this is an axonometric view.
-//        position in the view is parallel to the normal of the view
-//      - The distance position of the target camera is equal to the radius.
-
-  A = VX*VX + VY*VY + VZ*VZ ;
-  B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ);
-  C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ 
-    - Rayon*Rayon ;
-  Delta = B*B - 4.*A*C;
-  if ( Delta >= 0 ) {
-    Lambda = (-B + Sqrt(Delta))/(2.*A);
-    if ( Lambda >= -0.0001 && Lambda <= 0.0001 ) 
-      Lambda = (-B - Sqrt(Delta))/(2.*A);
-    X = XP + Lambda*VX;
-    Y = YP + Lambda*VY;
-    Z = ZP + Lambda*VZ;
-  }
-  else {
-    X = XP; Y = YP; Z = ZP;
-  }
-}
-
-// =======================================================================
-// function : IsDisplayed
-// purpose  :
-// =======================================================================
-Standard_Boolean V3d_Light::IsDisplayed() const
-{
-  if (myGraphicStructure.IsNull())
-  {
-    return Standard_False;
-  }
-
-  return myGraphicStructure->IsDisplayed();
-}
index 5b1fa55..26ef7c4 100644 (file)
 
 #include <Graphic3d_CLight.hxx>
 #include <V3d_TypeOfLight.hxx>
-#include <V3d_View.hxx>
 
-class Graphic3d_Structure;
-class V3d_Viewer;
-
-class V3d_Light;
-DEFINE_STANDARD_HANDLE(V3d_Light, Standard_Transient)
-
-//! Defines services on Light type objects..
-//! (base class for AmbientLight and PositionLight)
-class V3d_Light : public Standard_Transient
-{
-public:
-
-  //! Defines the color of a light source by giving the basic color.
-  Standard_EXPORT void SetColor (const Quantity_Color& theColor);
-
-  //! Returns the color of the light source.
-  Quantity_Color Color() const { return Quantity_Color (myLight.Color.rgb()); }
-
-  //! Returns the Type of the Light
-  Standard_EXPORT V3d_TypeOfLight Type() const;
-
-  //! returns true if the light is a headlight
-  Standard_EXPORT Standard_Boolean Headlight() const;
-
-  //! Setup headlight flag.
-  Standard_EXPORT void SetHeadlight (const Standard_Boolean theValue);
-
-  //! Modifies the intensity of light source.
-  Standard_EXPORT void SetIntensity (const Standard_Real theValue);
-
-  //! returns the intensity of light source
-  Standard_EXPORT Standard_Real Intensity() const;
-
-  //! returns the smoothness of light source
-  Standard_EXPORT Standard_Real Smoothness() const;
-
-  //! Returns TRUE when a light representation is displayed
-  Standard_EXPORT Standard_Boolean IsDisplayed() const;
-
-friend
-  //! Updates the lights of the view. The view is redrawn.
-  Standard_EXPORT void V3d_View::UpdateLights() const;
-
-  DEFINE_STANDARD_RTTIEXT(V3d_Light,Standard_Transient)
-
-protected:
-
-  Standard_EXPORT V3d_Light (const Handle(V3d_Viewer)& theViewer);
-
-  //! Sets type of the light.
-  Standard_EXPORT void SetType (const V3d_TypeOfLight theType);
-
-  //! Returns the symmetric point coordinates of "aPoint"
-  //! on the sphere of center "Center" and radius "Radius".
-  //! VX,VY,VZ is the project vector of view.
-  Standard_EXPORT static void SymetricPointOnSphere (const Handle(V3d_View)& aView,
-                                                     const gp_Pnt& Center,
-                                                     const gp_Pnt& aPoint,
-                                                     const Standard_Real Radius,
-                                                     Standard_Real& X, Standard_Real& Y, Standard_Real& Z,
-                                                     Standard_Real& VX, Standard_Real& VY, Standard_Real& VZ);
-
-protected:
-
-  //! Return light properties associated to this light source.
-  //! Hidden method exposed only to V3d_View.
-  Standard_EXPORT const Graphic3d_CLight& Light() const { return myLight; }
-
-protected:
-
-  Graphic3d_CLight myLight;
-  Handle(Graphic3d_Structure) myGraphicStructure;
-  Handle(Graphic3d_Structure) myGraphicStructure1;
-};
+typedef Graphic3d_CLight V3d_Light;
+typedef Handle_Graphic3d_CLight Handle_V3d_Light;
 
 #endif // _V3d_Light_HeaderFile
index f314aea..a8ececa 100644 (file)
 #ifndef _V3d_ListOfLight_HeaderFile
 #define _V3d_ListOfLight_HeaderFile
 
-class V3d_Light;
-#include <NCollection_List.hxx>
-#include <Standard_Transient.hxx>
+#include <V3d_Light.hxx>
 
-typedef NCollection_List<Handle(V3d_Light)> V3d_ListOfLight;
+typedef NCollection_List<Handle(Graphic3d_CLight)> V3d_ListOfLight;
 typedef V3d_ListOfLight::Iterator V3d_ListOfLightIterator;
 
 #endif // _V3d_ListOfLight_HeaderFile
index 3e2eab1..fae0432 100644 (file)
 
 #include <V3d_PositionLight.hxx>
 
-#include <gp_Dir.hxx>
-#include <gp_Vec.hxx>
-#include <Graphic3d_ArrayOfSegments.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_Group.hxx>
-#include <Graphic3d_Structure.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <V3d.hxx>
-#include <V3d_BadValue.hxx>
-#include <V3d_SpotLight.hxx>
-#include <V3d_View.hxx>
 #include <V3d_Viewer.hxx>
 
-IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionLight,V3d_Light)
+IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionLight, Graphic3d_CLight)
 
 // =======================================================================
 // function : V3d_PositionLight
 // purpose  :
 // =======================================================================
-V3d_PositionLight::V3d_PositionLight (const Handle(V3d_Viewer)& theViewer)
-: V3d_Light(theViewer)
+V3d_PositionLight::V3d_PositionLight (Graphic3d_TypeOfLightSource theType,
+                                      const Handle(V3d_Viewer)& theViewer)
+: Graphic3d_CLight (theType)
 {
-}
-
-// =======================================================================
-// function : SetTarget
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::SetTarget (const Standard_Real theX, const Standard_Real theY, const Standard_Real theZ)
-{
-  Standard_Real Xc,Yc,Zc, Xp,Yp,Zp;
-  
-  // Recalculation of the position
-  myTarget.Coord(Xc,Yc,Zc);
-  Position (Xp,Yp,Zp) ;
-
-  Xp = Xp + (theX - Xc);
-  Yp = Yp + (theY - Yc);
-  Zp = Zp + (theZ - Zc);
-
-  // Affectation
-  myTarget.SetCoord(theX,theY,theZ);
-  SetPosition(Xp,Yp,Zp) ;
-}
-
-// =======================================================================
-// function : SetRadius
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::SetRadius (const Standard_Real theRadius)
-{
-  V3d_BadValue_Raise_if( theRadius <= 0. , "V3d_PositionLight::SetRadius, bad radius");
-  V3d_BadValue_Raise_if( Type() == V3d_DIRECTIONAL , "V3d_PositionLight::SetRadius, bad light type");
-
-  // The target point remains unchanged, only the position of the light is modified by preserving the direction
-  gp_XYZ aPosOld;
-  Position (aPosOld.ChangeCoord (1), aPosOld.ChangeCoord (2), aPosOld.ChangeCoord (3));
-  gp_XYZ aDir = aPosOld - myTarget.XYZ();
-  aDir.Normalize();
-
-  const gp_XYZ aPosNew = myTarget.XYZ() + aDir * theRadius;
-  SetPosition (aPosNew.X(), aPosNew.Y(), aPosNew.Z());
-}
-
-// =======================================================================
-// function : OnHideFace
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::OnHideFace (const Handle(V3d_View)& theView)
-{
-  Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ;
-  
-  Position (Xp,Yp,Zp);
-  V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ);
-
-  // This is a visible point
-  if ((VX*(X-Xp) < 0.) && (VY*(Y-Yp) < 0.) && (VZ*(Z-Zp) < 0.))
-    SetPosition (X,Y,Z);
-}
-
-// =======================================================================
-// function : OnSeeFace
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::OnSeeFace (const Handle(V3d_View)& theView)
-{
-  Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ;
-  
-  Position (Xp,Yp,Zp);
-  V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ);
-
-  // This is a hidden point
-  if ((VX*(X-Xp) > 0.) && (VY*(Y-Yp) > 0.) && (VZ*(Z-Zp) > 0.))
-    SetPosition (X,Y,Z);
-}
-
-// =======================================================================
-// function : SeeOrHide
-// purpose  :
-// =======================================================================
-Standard_Boolean V3d_PositionLight::SeeOrHide (const Handle(V3d_View)& theView) const
-{
-  Standard_Real Xp,Yp,Zp, X,Y,Z, VX,VY,VZ;
-  
-  Position (Xp,Yp,Zp);
-  V3d_Light::SymetricPointOnSphere (theView, myTarget, gp_Pnt(Xp,Yp,Yp), Radius(), X,Y,Z, VX,VY,VZ);
-
-  // Is it a visible or a hidden point
-  return ( (VX*(X-Xp) > 0.) || (VY*(Y-Yp) > 0.) || (VZ*(Z-Zp) > 0.) )?
-    // the source is on the hidden face 
-    Standard_False:
-    // the source is on the visible face.
-    Standard_True;
-}
-
-// =======================================================================
-// function : Display
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::Display (const Handle(V3d_View)& theView, const V3d_TypeOfRepresentation theTPres)
-{
-  Graphic3d_Vertex PText ;
-  Standard_Real X,Y,Z,Rayon;
-  Standard_Real X0,Y0,Z0,VX,VY,VZ;
-  Standard_Real X1,Y1,Z1;
-  Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
-  V3d_TypeOfRepresentation Pres;
-
-//  Creation of a structure of markable elements (position of the
-//  light, and the domain of lighting represented by a circle)
-//  Creation of a structure snopick of non-markable elements (target, meridian and 
-//  parallel).
-
-  Pres = theTPres;
-  Handle(V3d_Viewer) TheViewer = theView->Viewer();
-  if (!myGraphicStructure.IsNull()) {
-    myGraphicStructure->Disconnect(myGraphicStructure1);
-    myGraphicStructure->Clear();
-    myGraphicStructure1->Clear();
-    if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation;
-  }
-  else {
-    if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
-    Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager());
-    myGraphicStructure = slight;
-    Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); 
-    myGraphicStructure1 = snopick;
-  }
-
-  Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow;
-  if (Type() != V3d_DIRECTIONAL
-   && Pres == V3d_COMPLETE)
-  {
-    gradius   = myGraphicStructure->NewGroup();
-    gExtArrow = myGraphicStructure->NewGroup();
-    gIntArrow = myGraphicStructure->NewGroup();
-  }
-  Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup();
-  Handle(Graphic3d_Group) gsphere;
-  if (Pres == V3d_COMPLETE
-   || Pres == V3d_PARTIAL)
+  if (!theViewer.IsNull())
   {
-    gsphere = myGraphicStructure->NewGroup();
+    theViewer->AddLight (this);
   }
-  
-  Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup();
-  
-  X0 = myTarget.X();
-  Y0 = myTarget.Y();
-  Z0 = myTarget.Z();
-  
-// Display of the light position.
-
-  const Quantity_Color Col1 = this->Color();
-  Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
-  Asp1->SetColor(Col1);
-  glight->SetPrimitivesAspect(Asp1);
-  this->Symbol(glight,theView);
-
-// Display of the marking sphere (limit at the circle).
-
-  if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
-      
-    Rayon = this->Radius();
-    theView->Proj(VX,VY,VZ);
-    V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
-
-    if (Type() != V3d_DIRECTIONAL) {
-
-      //Display of the radius of the sphere (line + text)
-
-      if (Pres == V3d_COMPLETE) {
-        this->Position(X,Y,Z);
-        Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
-        aPrims->AddVertex(X0,Y0,Z0);
-        aPrims->AddVertex(X,Y,Z);
-        gnopick->AddPrimitiveArray(aPrims);
-        V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.);
-        V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,M_PI/15.,Rayon/20.);
-        TCollection_AsciiString ValOfRadius(Rayon);
-        PText.SetCoord( .5*(X0+X), .5*(Y0+Y), .5*(Z0+Z) );
-        gradius->Text(ValOfRadius.ToCString(),PText,0.01);
-      }
-    }
-
-    // Display of the meridian
-
-    Quantity_Color Col2(Quantity_NOC_GREEN);
-    Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.);
-    gnopick->SetPrimitivesAspect(Asp2);
-    
-    // Definition of the axis of circle
-    theView->Up(DXRef,DYRef,DZRef);
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-      
-    // Display of the parallel
-
-    // Definition of the axis of circle
-    theView->Proj(VX,VY,VZ);
-    theView->Up(X1,Y1,Z1);
-    DXRef = VY * Z1 - VZ * Y1;
-    DYRef = VZ * X1 - VX * Z1;
-    DZRef = VX * Y1 - VY * X1;
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-  }
-
-  myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT);
-  myTypeOfRepresentation = Pres;
-  myGraphicStructure->Display();
 }
-
-// =======================================================================
-// function : Display
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::Tracking (const Handle(V3d_View)& theView,
-                                  const V3d_TypeOfPickLight theWhatPick,
-                                  const Standard_Integer theXpix,
-                                  const Standard_Integer theYpix)
-{
-  Standard_Real    XPp,YPp,PXT,PYT,X,Y,Z,Rayon,Ylim;
-  Standard_Real    XMinTrack,XMaxTrack,YMinTrack,YMaxTrack;
-  Standard_Real    XT,YT,ZT,X0,Y0,Z0,XP,YP,ZP,VX,VY,VZ,A,B,C,Delta;
-  Standard_Real    DX,DY,PXP,PYP,Xproj,Yproj;
-  Standard_Real    A1,A2,B1,B2,Rap,OldRprj,NewRprj;
-  Standard_Real    Xi,Yi,Zi,DeltaX,DeltaY,DeltaZ,Lambda;
-  Standard_Integer IPX,IPY;
-  
-  theView->Convert(theXpix,theYpix,XPp,YPp);
-  X0 = myTarget.X();
-  Y0 = myTarget.Y();
-  Z0 = myTarget.Z();
-  theView->Project(X0,Y0,Z0,PXT,PYT);
-  theView->Convert(PXT,PYT,IPX,IPY);
-//      Coord 3d in the plane of projection of the target.
-  theView->Convert(IPX,IPY,XT,YT,ZT);
-  switch (theWhatPick) {
-  case V3d_POSITIONLIGHT :
-         // The Coordinates should remain inside of the sphere
-    Rayon = Radius();
-    XMinTrack = PXT - Rayon;
-    XMaxTrack = PXT + Rayon;
-    Ylim = Sqrt( Square(Rayon) - Square(XPp - PXT) );
-    YMinTrack = PYT - Ylim;
-    YMaxTrack = PYT + Ylim;
-    if (XPp >= XMinTrack && XPp <= XMaxTrack) {
-      if (YPp >= YMinTrack && YPp <= YMaxTrack) {
-                               theView->ProjReferenceAxe(theXpix,theYpix,XP,YP,ZP,VX,VY,VZ);
-       DeltaX = X0 - XP;
-       DeltaY = Y0 - YP;
-       DeltaZ = Z0 - ZP;
-       
-//      The point of intersection of straight lines defined by :
-//      - Straight line passing by the point of projection and the eye
-//        if this is a perspective, parralel to the normal of the view 
-//        if this is an axonometric view.
-//        position in the view is parallel to the normal of the view
-//      - The distance position of the target camera is equal to the radius.
-
-       A = VX*VX + VY*VY + VZ*VZ ;
-       B = -2. * (VX*DeltaX + VY*DeltaY + VZ*DeltaZ);
-       C = DeltaX*DeltaX + DeltaY*DeltaY + DeltaZ*DeltaZ 
-         - Rayon*Rayon ;
-       Delta = B*B - 4.*A*C;
-       if ( Delta >= 0 ) {
-         Lambda = (-B + Sqrt(Delta))/(2.*A);
-         X = XP + Lambda*VX;
-         Y = YP + Lambda*VY;
-         Z = ZP + Lambda*VZ;
-         SetPosition(X,Y,Z);
-
-               if (Type() == V3d_SPOT)
-           ((V3d_SpotLight*)this)->SetDirection(X0-X,Y0-Y,Z0-Z);
-
-         Display(theView,myTypeOfRepresentation);
-         (theView->Viewer())->UpdateLights();
-       }
-      }
-    }
-    break;
-
-  case V3d_SPACELIGHT :
-    theView->Convert(PXT,PYT,IPX,IPY);
-//               In this case Xpix,Ypix correspond to a distance, relative
-//               to the translation that is planned to be performed on the sphere. 
-    theView->Convert(IPX+theXpix,IPY+theYpix,X,Y,Z);
-    X = X+X0-XT;
-    Y = Y+Y0-YT; 
-    Z = Z+Z0-ZT;
-    SetTarget(X,Y,Z);
-    Display(theView,myTypeOfRepresentation);
-    (theView->Viewer())->UpdateLights();
-    break;
-
-  case V3d_ExtRADIUSLIGHT :
-               if (Type() == V3d_DIRECTIONAL)
-                       break;
-//             it is attempted to preserve the target direction position of the  
-//             source ==> the point is projected on the target source direction.
-    this->Position(Xi,Yi,Zi);
-    theView->Project(Xi,Yi,Zi,PXP,PYP);
-    DX = PXP - PXT;
-    DY = PYP - PYT;
-    A1 = DY/DX ; B1 = PYT - A1*PXT;
-    A2 = -DX/DY; B2 = YPp - A2*XPp;
-    Xproj = (B2 - B1) / (A1 - A2);
-    Yproj = A1*Xproj + B1;
-    if ( (DX*(Xproj-PXT) > 0.) && (DY*(Yproj-PYT) > 0.) ) {
-      OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) );
-      NewRprj = Sqrt ( Square (Xproj-PXT) + Square (Yproj-PYT) );
-      Rap = NewRprj/OldRprj;
-      Rayon = Radius();
-      Rayon = Rayon * Rap;
-      SetRadius(Rayon);
-      Display(theView,myTypeOfRepresentation);
-      (theView->Viewer())->UpdateLights();
-    }
-    break;
-
-  case V3d_IntRADIUSLIGHT :
-               if (Type() == V3d_DIRECTIONAL)
-                       break;
-//             it is attempted to preserve the target direction position of the  
-//             source ==> the point is projected on the target source direction.
-    Position(Xi,Yi,Zi);
-    theView->Project(Xi,Yi,Zi,PXP,PYP);
-    DX = PXP - PXT;
-    DY = PYP - PYT;
-    A1 = DY/DX ; B1 = PYT - A1*PXT;
-    A2 = -DX/DY; B2 = YPp - A2*XPp;
-    Xproj = (B2 - B1) / (A1 - A2);
-    Yproj = A1*Xproj + B1;
-    if ( (DX*(Xproj-PXP) < 0.) && (DY*(Yproj-PYP) < 0.) ) {
-      OldRprj = Sqrt ( Square (PXP-PXT) + Square (PYP-PYT) );
-      NewRprj = Sqrt ( Square (Xproj-PXP) + Square (Yproj-PYP) );
-      Rap = NewRprj/OldRprj;
-      Rayon = Radius();
-      Rayon = Rayon * Rap;
-//                 the source should remain at a fixed position, 
-//                 only the target is modified.
-
-      gp_XYZ aPos;
-      Position (aPos.ChangeCoord (1), aPos.ChangeCoord (2), aPos.ChangeCoord (3));
-      gp_XYZ aDir = myTarget.XYZ() - aPos;
-      aDir.Normalize();
-      aDir.Coord(X,Y,Z);
-      X = Xi + Rayon*X;
-      Y = Yi + Rayon*Y;
-      Z = Zi + Rayon*Z;
-//                 the source should remain at a fixed position, 
-//                 only the target is modified.
-      myTarget.SetCoord(X,Y,Z);
-      Display(theView,myTypeOfRepresentation);          
-      (theView->Viewer())->UpdateLights();
-    }
-               break;
-
-  case V3d_RADIUSTEXTLIGHT :
-    break;
-
-  case V3d_NOTHING : 
-    break;
-  }
-}
-
-// =======================================================================
-// function : Radius
-// purpose  :
-// =======================================================================
-Standard_Real V3d_PositionLight::Radius() const
-{
-  Standard_Real  Xp,Yp,Zp, Xc,Yc,Zc;
-  
-  Position (Xp,Yp,Zp);
-  myTarget.Coord(Xc,Yc,Zc);
-
-  return Sqrt (Square(Xc - Xp) + Square(Yc - Yp) + Square(Zc - Zp));
-}
-
-// =======================================================================
-// function : Erase
-// purpose  :
-// =======================================================================
-void V3d_PositionLight::Erase()
-{
-  if (!myGraphicStructure.IsNull()) myGraphicStructure->Erase();
-  if (!myGraphicStructure1.IsNull()) myGraphicStructure1->Erase();
-}
-
index 53a9c50..f1a656c 100644 (file)
 #include <V3d_TypeOfPickLight.hxx>
 #include <V3d_TypeOfRepresentation.hxx>
 
-class V3d_View;
 class V3d_Viewer;
-class V3d_PositionLight;
-DEFINE_STANDARD_HANDLE(V3d_PositionLight, V3d_Light)
 
 //! Base class for Positional, Spot and Directional Light classes.
-class V3d_PositionLight : public V3d_Light
+class V3d_PositionLight : public Graphic3d_CLight
 {
-public:
-
-  //! Defines the position of the light source. Should be redefined!
-  Standard_EXPORT virtual void SetPosition (Standard_Real theX,
-                                            Standard_Real theY,
-                                            Standard_Real theZ) = 0;
-
-  //! Defines the target of the light (the center of the sphere).
-  Standard_EXPORT void SetTarget (const Standard_Real theX,
-                                  const Standard_Real theY,
-                                  const Standard_Real theZ);
-
-  //! Define the radius.
-  Standard_EXPORT void SetRadius (const Standard_Real theRadius);
-
-  //! Calculate the position of the light, on the hide face of the picking sphere.
-  Standard_EXPORT void OnHideFace (const Handle(V3d_View)& theView);
-
-  //! Calculate the position of the light, on the seen face of the picking sphere.
-  Standard_EXPORT void OnSeeFace (const Handle(V3d_View)& theView);
-
-  //! Tracking the light position, or the light space,
-  //! or the radius of the light space, that depends of
-  //! initial picking "theWhatPick" (see the pick method).
-  //! If theWhatPick is SPACELIGHT, then the parameters
-  //! theXpix, theYpix are the coordinates of a translation vector.
-  Standard_EXPORT void Tracking (const Handle(V3d_View)& theView,
-                                 const V3d_TypeOfPickLight theWathPick,
-                                 const Standard_Integer theXpix,
-                                 const Standard_Integer theYpix);
-
-  //! Display the graphic structure of light source
-  //! in the chosen view. We have three type of representation
-  //! - SIMPLE   : Only the light source is displayed.
-  //! - PARTIAL  : The light source and the light space are
-  //! displayed.
-  //! - COMPLETE : The light source, the light space and the
-  //! radius of light space are displayed.
-  //! We can choose the "SAMELAST" as parameter of representation
-  //! In this case the graphic structure representation will be
-  //! the last displayed.
-  Standard_EXPORT virtual void Display (const Handle(V3d_View)& theView,
-                                        const V3d_TypeOfRepresentation theRepresentation = V3d_SIMPLE);
-
-  //! Erase the graphic structure of light source.
-  Standard_EXPORT void Erase();
-
-  //! Returns the radius of the picking sphere.
-  Standard_EXPORT Standard_Real Radius() const;
-
-  //! Returns the visibility status
-  //! If True the source is visible.
-  //! If False it's hidden.
-  Standard_EXPORT Standard_Boolean SeeOrHide (const Handle(V3d_View)& theView) const;
-
-  //! Returns the position of the light source.
-  Standard_EXPORT virtual void Position (Standard_Real& theX,
-                                         Standard_Real& theY,
-                                         Standard_Real& theZ) const = 0;
-
-  //! Returns the position of the target of the light source.
-  void Target (Standard_Real& theX,
-               Standard_Real& theY,
-               Standard_Real& theZ) const { myTarget.Coord (theX, theY, theZ); }
-
-  DEFINE_STANDARD_RTTIEXT(V3d_PositionLight,V3d_Light)
-
+  DEFINE_STANDARD_RTTIEXT(V3d_PositionLight, Graphic3d_CLight)
 protected:
 
-  Standard_EXPORT V3d_PositionLight (const Handle(V3d_Viewer)& theViewer);
+  //! Protected constructor.
+  Standard_EXPORT V3d_PositionLight (Graphic3d_TypeOfLightSource theType,
+                                     const Handle(V3d_Viewer)& theViewer);
 
+//! @name hidden properties not applicable to positional light
 protected:
 
-  gp_Pnt myTarget;
-  V3d_TypeOfRepresentation myTypeOfRepresentation;
+  using Graphic3d_CLight::Position;
+  using Graphic3d_CLight::SetPosition;
 
-private:
-
-  //! Defines representation of the light source.
-  Standard_EXPORT virtual void Symbol (const Handle(Graphic3d_Group)& theSymbol,
-                                       const Handle(V3d_View)& theView) const = 0;
 };
 
+DEFINE_STANDARD_HANDLE(V3d_PositionLight, Graphic3d_CLight)
+
 #endif // _V3d_PositionLight_HeaderFile
index a9456cd..9cc8660 100644 (file)
 
 #include <V3d_PositionalLight.hxx>
 
-#include <Graphic3d_ArrayOfSegments.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_Group.hxx>
-#include <Graphic3d_Structure.hxx>
-#include <TCollection_AsciiString.hxx>
-#include <TColStd_Array2OfReal.hxx>
-#include <V3d.hxx>
-#include <V3d_BadValue.hxx>
-#include <V3d_View.hxx>
-#include <V3d_Viewer.hxx>
-
 IMPLEMENT_STANDARD_RTTIEXT(V3d_PositionalLight,V3d_PositionLight)
 
 // =======================================================================
 // function : V3d_PositionalLight
 // purpose  :
 // =======================================================================
-V3d_PositionalLight::V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer,
-                                          const Standard_Real theX,
-                                          const Standard_Real theY,
-                                          const Standard_Real theZ,
-                                          const Quantity_Color& theColor,
-                                          const Standard_Real theConstAttenuation,
-                                          const Standard_Real theLinearAttenuation)
-: V3d_PositionLight (theViewer)
+V3d_PositionalLight::V3d_PositionalLight (const gp_Pnt& thePos,
+                                          const Quantity_Color& theColor)
+: V3d_PositionLight (Graphic3d_TOLS_POSITIONAL, Handle(V3d_Viewer)())
 {
-  SetType (V3d_POSITIONAL);
   SetColor (theColor);
-  SetTarget (0., 0., 0.);
-  SetPosition (theX, theY, theZ);
-  SetAttenuation (theConstAttenuation, theLinearAttenuation);
+  SetPosition (thePos);
 }
 
 // =======================================================================
@@ -51,230 +32,15 @@ V3d_PositionalLight::V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer,
 // purpose  :
 // =======================================================================
 V3d_PositionalLight::V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer,
-                                          const Standard_Real theXt,
-                                          const Standard_Real theYt,
-                                          const Standard_Real theZt,
-                                          const Standard_Real theXp,
-                                          const Standard_Real theYp,
-                                          const Standard_Real theZp,
+                                          const Standard_Real theX,
+                                          const Standard_Real theY,
+                                          const Standard_Real theZ,
                                           const Quantity_Color& theColor,
                                           const Standard_Real theConstAttenuation,
                                           const Standard_Real theLinearAttenuation)
-: V3d_PositionLight (theViewer)
+: V3d_PositionLight (Graphic3d_TOLS_POSITIONAL, theViewer)
 {
-  SetType (V3d_POSITIONAL);
   SetColor (theColor);
-  SetTarget (theXt, theYt, theZt);
-  SetPosition (theXp, theYp, theZp);
-  SetAttenuation (theConstAttenuation, theLinearAttenuation);
-}
-
-// =======================================================================
-// function : SetSmoothRadius
-// purpose  :
-// =======================================================================
-void V3d_PositionalLight::SetSmoothRadius (const Standard_Real theValue)
-{
-  V3d_BadValue_Raise_if (theValue < 0.0,
-    "V3d_PositionalLight::SetSmoothRadius,"
-    "Bad value for smoothing radius");
-
-  myLight.Smoothness = static_cast<Standard_ShortReal> (theValue);
-}
-
-// =======================================================================
-// function : SetAttenuation
-// purpose  :
-// =======================================================================
-void V3d_PositionalLight::SetAttenuation (const Standard_Real theConstAttenuation,
-                                          const Standard_Real theLinearAttenuation)
-{
-  V3d_BadValue_Raise_if (theConstAttenuation < 0.
-                      || theConstAttenuation > 1.
-                      || theLinearAttenuation < 0.
-                      || theLinearAttenuation > 1.,
-    "V3d_PositionalLight::SetAttenuation, bad coefficients");
-
-  myLight.ChangeConstAttenuation()  = static_cast<Standard_ShortReal> (theConstAttenuation);
-  myLight.ChangeLinearAttenuation() = static_cast<Standard_ShortReal> (theLinearAttenuation);
-}
-
-// =======================================================================
-// function : Symbol
-// purpose  :
-// =======================================================================
-void V3d_PositionalLight::Symbol (const Handle(Graphic3d_Group)& theSymbol, const Handle(V3d_View)& theView) const
-{
-  Standard_Real Xi,Yi,Zi,Xf,Yf,Zf,Rayon,PXT,PYT,X,Y,Z,XT,YT,ZT;
-  Standard_Real A,B,C,Dist,Beta,CosBeta,SinBeta,Coef,X1,Y1,Z1;
-  Standard_Real VX,VY,VZ;
-  Standard_Integer IXP,IYP,j;
-  TColStd_Array2OfReal MatRot(0,2,0,2);
-
-  theView->Proj(VX,VY,VZ);
-  this->Position(Xi,Yi,Zi);
-  Rayon = this->Radius();
-  theView->Project(Xi,Yi,Zi,PXT,PYT); 
-  theView->Convert(PXT,PYT,IXP,IYP);
-//  3D Coordinate in the plane of projection of the source.
-  theView->Convert(IXP,IYP,XT,YT,ZT);
-  theView->Convert(PXT,PYT+Rayon,IXP,IYP);
-  theView->Convert(IXP,IYP,X,Y,Z);
-  X = X+Xi-XT; Y = Y+Yi-YT; Z = Z+Zi-ZT;
-  Dist = Sqrt( Square(X-Xi) + Square(Y-Yi) + Square(Z-Zi) );
-//  Axis of rotation.
-  A = (X-Xi)/Dist;
-  B = (Y-Yi)/Dist;
-  C = (Z-Zi)/Dist;
-
-//  A sphere is drawn
-  V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
-  for( j=1 ; j<=3 ; j++ ) {
-    Beta = j * M_PI / 4.;
-    CosBeta = Cos(Beta);
-    SinBeta = Sin(Beta);
-    Coef = 1. - CosBeta;
-    MatRot(0,0) =  A * A + (1. - A * A) * CosBeta;
-    MatRot(0,1) = -C * SinBeta + Coef * A * B;
-    MatRot(0,2) =  B * SinBeta + Coef * A * C;
-    MatRot(1,0) =  C * SinBeta + Coef * A * B; 
-    MatRot(1,1) =  B * B + (1. - B * B) * CosBeta;
-    MatRot(1,2) = -A * SinBeta + Coef * B * C;
-    MatRot(2,0) = -B * SinBeta + Coef * A * C;
-    MatRot(2,1) =  A * SinBeta + Coef * B * C;
-    MatRot(2,2) =  C * C + (1. - C * C) * CosBeta;
-    Xf = Xi * MatRot(0,0) + Yi * MatRot(0,1) + Zi * MatRot(0,2);
-    Yf = Xi * MatRot(1,0) + Yi * MatRot(1,1) + Zi * MatRot(1,2);
-    Zf = Xi * MatRot(2,0) + Yi * MatRot(2,1) + Zi * MatRot(2,2);
-//    Rotation of the normal
-    X1 = VX * MatRot(0,0) + VY * MatRot(0,1) + VZ * MatRot(0,2);
-    Y1 = VX * MatRot(1,0) + VY * MatRot(1,1) + VZ * MatRot(1,2);
-    Z1 = VX * MatRot(2,0) + VY * MatRot(2,1) + VZ * MatRot(2,2);
-    VX = X1 + Xi - Xf ; VY = Y1 + Yi - Yf ; VZ = Z1 + Zi - Zf;
-    V3d::CircleInPlane(theSymbol,Xi,Yi,Zi,VX,VY,VZ,Rayon/40.);
-  }
-}
-
-// =======================================================================
-// function : Display
-// purpose  :
-// =======================================================================
-void V3d_PositionalLight::Display (const Handle(V3d_View)& theView,
-                                   const V3d_TypeOfRepresentation theRepresentation)
-{
-  Standard_Real X,Y,Z,Rayon;
-  Standard_Real X0,Y0,Z0,VX,VY,VZ;
-  Standard_Real X1,Y1,Z1;
-  Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
-  V3d_TypeOfRepresentation Pres;
-
-//  Creation of a structure slight of markable elements (position of the
-//  light, and the domain of lighting represented by a circle)
-//  Creation of a structure snopick of non-markable elements (target, meridian and 
-//  parallel).
-
-  Pres = theRepresentation;
-  Handle(V3d_Viewer) TheViewer = theView->Viewer();
-  if (!myGraphicStructure.IsNull()) {
-    myGraphicStructure->Disconnect(myGraphicStructure1);
-    myGraphicStructure->Clear();
-    myGraphicStructure1->Clear();
-    if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation;
-  }
-  else {
-    if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
-    Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager());
-    myGraphicStructure = slight;
-    Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); 
-    myGraphicStructure1 = snopick;
-  }
-
-  Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow;
-  if (Pres == V3d_COMPLETE)
-  {
-    gradius   = myGraphicStructure->NewGroup();
-    gExtArrow = myGraphicStructure->NewGroup();
-    gIntArrow = myGraphicStructure->NewGroup();
-  }
-  Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup();
-  Handle(Graphic3d_Group) gsphere;
-  if (Pres == V3d_COMPLETE
-   || Pres == V3d_PARTIAL)
-  {
-    gsphere = myGraphicStructure->NewGroup();
-  }
-  
-  Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup();
-  
-  X0 = myTarget.X();
-  Y0 = myTarget.Y();
-  Z0 = myTarget.Z();
-  
-// Display of the position of the light.
-
-  const Quantity_Color Col1 = this->Color();
-  Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
-  Asp1->SetColor(Col1);
-  glight->SetPrimitivesAspect(Asp1);
-  this->Symbol(glight,theView);
-
-// Display of the markable sphere (limit at the cercle).
-
-  if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
-      
-    Rayon = this->Radius();
-    theView->Proj(VX,VY,VZ);
-    V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
-
-// Display of the radius of the sphere (line + text)
-
-    if (Pres == V3d_COMPLETE) {
-      this->Position(X,Y,Z);
-      Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
-      aPrims->AddVertex(X0,Y0,Z0);
-      aPrims->AddVertex(X,Y,Z);
-      gnopick->AddPrimitiveArray(aPrims);
-      V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.);
-      V3d::ArrowOfRadius(gIntArrow, X0, Y0, Z0, X0-X, Y0-Y, Z0-Z, M_PI / 15., Rayon / 20.);
-      TCollection_AsciiString ValOfRadius(Rayon);
-      Graphic3d_Vertex PText (0.5*(X0+X), 0.5*(Y0+Y), 0.5*(Z0+Z));
-      gradius->Text(ValOfRadius.ToCString(),PText,0.01);
-    }
-    
-// Display of the meridian
-
-    Quantity_Color Col2(Quantity_NOC_GREEN);
-    Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.);
-    gnopick->SetPrimitivesAspect(Asp2);
-    
-//    Definition of the axis of circle
-    theView->Up(DXRef,DYRef,DZRef);
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-      
-//  Display of the parallel
-
-//  Definition of the axis of circle
-    theView->Proj(VX,VY,VZ);
-    theView->Up(X1,Y1,Z1);
-    DXRef = VY * Z1 - VZ * Y1;
-    DYRef = VZ * X1 - VX * Z1;
-    DZRef = VX * Y1 - VY * X1;
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-  }
-
-  myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT);
-  myTypeOfRepresentation = Pres;
-  myGraphicStructure->Display();
+  SetPosition (theX, theY, theZ);
+  SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation);
 }
index 0993d9d..33905e5 100644 (file)
 
 #include <V3d_PositionLight.hxx>
 
-class V3d_PositionalLight;
-DEFINE_STANDARD_HANDLE(V3d_PositionalLight, V3d_PositionLight)
-
-//! Creation and modification of an isolated
-//! (positional) light source.
+//! Creation and modification of an isolated (positional) light source.
+//! It is also defined by the color and two attenuation factors ConstAttentuation() and LinearAttentuation().
+//! The resulting attenuation factor determining the illumination of a surface depends on the following formula:
+//! @code
+//!   F = 1 / (ConstAttenuation() + LinearAttenuation() * Distance)
+//! @endcode
+//! Where Distance is the distance of the isolated source from the surface.
 class V3d_PositionalLight : public V3d_PositionLight
 {
+  DEFINE_STANDARD_RTTIEXT(V3d_PositionalLight, V3d_PositionLight)
+public:
+
+  //! Creates an isolated light source in the viewer with default attenuation factors (1.0, 0.0).
+  Standard_EXPORT V3d_PositionalLight (const gp_Pnt& thePos,
+                                       const Quantity_Color& theColor = Quantity_NOC_WHITE);
+
+  using Graphic3d_CLight::Position;
+  using Graphic3d_CLight::SetPosition;
+
 public:
 
-  //! Creates an isolated light source theX, theY, theZ in the viewer.
-  //! It is also defined by the color theColor and
-  //! two attenuation factors theConstAttentuation, theLinearAttentuation.
-  //! The resulting attenuation factor determining the
-  //! illumination of a surface depends on the following
-  //! formula :
-  //! F = 1/(ConstAttenuation + LinearAttenuation*Length)
-  //! Length is the distance of the isolated source
-  //! from the surface.  //! Warning!  raises BadValue from V3d
-  //! if one of the attenuation coefficients is not in range [0, 1].
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer,
                                        const Standard_Real theX,
                                        const Standard_Real theY,
@@ -46,85 +49,18 @@ public:
                                        const Standard_Real theConstAttenuation = 1.0,
                                        const Standard_Real theLinearAttenuation = 0.0);
 
-  //! Creates a light source of the Positional type in the viewer.
-  //! theXt, theYt, theZt : Coordinate of Target light source.
-  //! theXp, theYp, theZp : Coordinate of Position light source.
-  //! The light source is also defined by the color Color
-  //! and two attenuation factors theConstAttentuation,
-  //! theLinearAttentuation that determine the illumination of a
-  //! surface using the following formula :
-  //! F = 1/(ConstAttenuation + LinearAttenuation*Length)
-  //! Length is the distance of the isolated source
-  //! from the surface.  //! Warning! raises BadValue from V3d
-  //! if one of the attenuation coefficients is not between 0 et 1.
-  Standard_EXPORT V3d_PositionalLight (const Handle(V3d_Viewer)& theViewer,
-                                       const Standard_Real theXt,
-                                       const Standard_Real theYt,
-                                       const Standard_Real theZt,
-                                       const Standard_Real theXp,
-                                       const Standard_Real theYp,
-                                       const Standard_Real theZp,
-                                       const Quantity_Color& theColor = Quantity_NOC_WHITE,
-                                       const Standard_Real theConstAttenuation = 1.0,
-                                       const Standard_Real theLinearAttenuation = 0.0);
-
-  //! Defines the position of the light source.
-  virtual void SetPosition (Standard_Real theX,
-                            Standard_Real theY,
-                            Standard_Real theZ) Standard_OVERRIDE
-  {
-    myLight.Position.x() = theX;
-    myLight.Position.y() = theY;
-    myLight.Position.z() = theZ;
-  }
-
-  //! Defines the attenuation factors.
-  //! Warning: raises BadValue from V3d
-  //! if one of the attenuation coefficients is not between 0 et 1.
-  Standard_EXPORT void SetAttenuation (const Standard_Real theConstAttenuation,
-                                       const Standard_Real theLinearAttenuation);
-
-  //! Modifies the smoothing radius
-  Standard_EXPORT void SetSmoothRadius (const Standard_Real theValue);
-
-  //! Display the graphic structure of light source
-  //! in the chosen view. We have three type of representation
-  //! - SIMPLE   : Only the light source is displayed.
-  //! - PARTIAL  : The light source and the light space are
-  //! displayed.
-  //! - COMPLETE : The light source, the light space and the
-  //! radius of light space are displayed.
-  //! We can choose the "SAMELAST" as parameter of representation
-  //! In this case the graphic structure representation will be
-  //! the last displayed.
-  Standard_EXPORT void Display (const Handle(V3d_View)& theView,
-                                const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE;
-
-  //! Returns the position of the light source.
-  void Position (Standard_Real& theX,
-                 Standard_Real& theY,
-                 Standard_Real& theZ) const Standard_OVERRIDE
-  {
-    theX = myLight.Position.x();
-    theY = myLight.Position.y();
-    theZ = myLight.Position.z();
-  }
-
-  //! Returns the attenuation factors.
-  void Attenuation (Standard_Real& theConstAttenuation,
-                    Standard_Real& theLinearAttenuation) const
-  {
-    theConstAttenuation  = myLight.ConstAttenuation();
-    theLinearAttenuation = myLight.LinearAttenuation();
-  }
-
-  DEFINE_STANDARD_RTTIEXT(V3d_PositionalLight,V3d_PositionLight)
-
+//! @name hidden properties not applicable to positional light
 private:
 
-  //! Defined the representation of the positional light source.
-  Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol,
-                               const Handle(V3d_View)& theView) const Standard_OVERRIDE;
+  using Graphic3d_CLight::Direction;
+  using Graphic3d_CLight::SetDirection;
+  using Graphic3d_CLight::Angle;
+  using Graphic3d_CLight::SetAngle;
+  using Graphic3d_CLight::Concentration;
+  using Graphic3d_CLight::SetConcentration;
+
 };
 
+DEFINE_STANDARD_HANDLE(V3d_PositionalLight, V3d_PositionLight)
+
 #endif // _V3d_PositionalLight_HeaderFile
index 53a8fa5..1329ec3 100644 (file)
 
 #include <V3d_SpotLight.hxx>
 
-#include <Graphic3d_ArrayOfSegments.hxx>
-#include <Graphic3d_AspectLine3d.hxx>
-#include <Graphic3d_Group.hxx>
-#include <Graphic3d_Structure.hxx>
-#include <TCollection_AsciiString.hxx>
 #include <V3d.hxx>
-#include <V3d_BadValue.hxx>
-#include <V3d_View.hxx>
-#include <V3d_Viewer.hxx>
 
 IMPLEMENT_STANDARD_RTTIEXT(V3d_SpotLight,V3d_PositionLight)
 
+// =======================================================================
+// function : V3d_SpotLight
+// purpose  :
+// =======================================================================
+V3d_SpotLight::V3d_SpotLight (const gp_Pnt& thePos,
+                              const V3d_TypeOfOrientation theDirection,
+                              const Quantity_Color& theColor)
+: V3d_PositionLight (Graphic3d_TOLS_SPOT, Handle(V3d_Viewer)())
+{
+  SetColor (theColor);
+  SetPosition (thePos);
+  SetDirection (V3d::GetProjAxis (theDirection));
+}
+
+// =======================================================================
+// function : V3d_SpotLight
+// purpose  :
+// =======================================================================
+V3d_SpotLight::V3d_SpotLight (const gp_Pnt& thePos,
+                              const gp_Dir& theDirection,
+                              const Quantity_Color& theColor)
+: V3d_PositionLight (Graphic3d_TOLS_SPOT, Handle(V3d_Viewer)())
+{
+  SetColor (theColor);
+  SetPosition (thePos);
+  SetDirection (theDirection);
+}
+
 // =======================================================================
 // function : V3d_SpotLight
 // purpose  :
@@ -39,17 +59,14 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer,
                               const Standard_Real theLinearAttenuation,
                               const Standard_Real theConcentration,
                               const Standard_Real theAngle)
-: V3d_PositionLight (theViewer)
+: V3d_PositionLight (Graphic3d_TOLS_SPOT, theViewer)
 {
-  gp_Dir aDir = V3d::GetProjAxis (theDirection);
-  SetType (V3d_SPOT);
   SetColor (theColor);
-  SetTarget (theX + aDir.X(), theY + aDir.Y(), theZ + aDir.Z());
   SetPosition (theX, theY, theZ);
-  SetDirection (aDir.X(), aDir.Y(), aDir.Z());
-  SetAttenuation (theConstAttenuation, theLinearAttenuation);
-  SetConcentration (theConcentration);
-  SetAngle (theAngle);
+  SetDirection (V3d::GetProjAxis (theDirection));
+  SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation);
+  SetConcentration ((float )theConcentration);
+  SetAngle ((float )theAngle);
 }
 
 // =======================================================================
@@ -68,16 +85,14 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer,
                               const Standard_Real theLinearAttenuation,
                               const Standard_Real theConcentration,
                               const Standard_Real theAngle)
-: V3d_PositionLight (theViewer)
+: V3d_PositionLight (Graphic3d_TOLS_SPOT, theViewer)
 {
-  SetType (V3d_SPOT);
   SetColor (theColor);
-  SetTarget (theXt, theYt, theZt);
   SetPosition (theXp, theYp, theZp);
   SetDirection (theXt - theXp, theYt - theYp, theZt - theZp);
-  SetAttenuation (theConstAttenuation, theLinearAttenuation);
-  SetConcentration (theConcentration);
-  SetAngle (theAngle);
+  SetAttenuation ((float )theConstAttenuation, (float )theLinearAttenuation);
+  SetConcentration ((float )theConcentration);
+  SetAngle ((float )theAngle);
 }
 
 // =======================================================================
@@ -86,190 +101,5 @@ V3d_SpotLight::V3d_SpotLight (const Handle(V3d_Viewer)& theViewer,
 // =======================================================================
 void V3d_SpotLight::SetDirection (V3d_TypeOfOrientation theDirection)
 {
-  gp_Dir aDir = V3d::GetProjAxis (theDirection);
-  SetDirection (aDir.X(), aDir.Y(), aDir.Z());
-}
-
-// =======================================================================
-// function : SetAttenuation
-// purpose  :
-// =======================================================================
-void V3d_SpotLight::SetAttenuation (const Standard_Real theConstAttenuation,
-                                    const Standard_Real theLinearAttenuation)
-{
-  V3d_BadValue_Raise_if (theConstAttenuation  < 0. ||
-                         theConstAttenuation  > 1. ||
-                         theLinearAttenuation < 0. ||
-                         theLinearAttenuation > 1 ,
-                         "V3d_SpotLight::SetAttenuation, "
-                         "bad coefficients");
-
-  myLight.ChangeConstAttenuation()  = static_cast<Standard_ShortReal> (theConstAttenuation);
-  myLight.ChangeLinearAttenuation() = static_cast<Standard_ShortReal> (theLinearAttenuation);
-}
-
-// =======================================================================
-// function : SetConcentration
-// purpose  :
-// =======================================================================
-void V3d_SpotLight::SetConcentration (const Standard_Real theConcentration)
-{
-  V3d_BadValue_Raise_if (theConcentration < 0. ||
-                         theConcentration > 1.,
-                         "V3d_SpotLight::SetConcentration, "
-                         "bad coefficient");
-
-  myLight.ChangeConcentration() = static_cast<Standard_ShortReal> (theConcentration);
-}
-
-// =======================================================================
-// function : SetAngle
-// purpose  :
-// =======================================================================
-void V3d_SpotLight::SetAngle (const Standard_Real theAngle)
-{
-  V3d_BadValue_Raise_if (theAngle <= 0. || 
-                         theAngle >= M_PI,
-                         "V3d_SpotLight::SetAngle, "
-                         "bad angle");
-
-  myLight.ChangeAngle() = static_cast<Standard_ShortReal> (theAngle);
-}
-// =======================================================================
-// function : Symbol
-// purpose  :
-// =======================================================================
-void V3d_SpotLight::Symbol (const Handle(Graphic3d_Group)& theSymbol,
-                            const Handle(V3d_View)& ) const
-{
-  Standard_Real X,Y,Z;
-  Standard_Real DX,DY,DZ;
-  this->Position(X,Y,Z);
-  this->Direction(DX,DY,DZ);
-
-  V3d::ArrowOfRadius(theSymbol,X,Y,Z,-DX,-DY,-DZ,M_PI/8.,this->Radius()/15.);
-}
-
-// =======================================================================
-// function : Display
-// purpose  :
-// =======================================================================
-void V3d_SpotLight::Display (const Handle(V3d_View)& theView,
-                             const V3d_TypeOfRepresentation theTPres)
-{
-  Standard_Real X,Y,Z,Rayon;
-  Standard_Real X0,Y0,Z0,VX,VY,VZ;
-  Standard_Real X1,Y1,Z1;
-  Standard_Real DXRef,DYRef,DZRef,DXini,DYini,DZini;
-  V3d_TypeOfRepresentation Pres;
-
-//  Creation of a structure slight of markable elements (position of the
-//  light, and the domain of lighting represented by a circle)
-//  Creation of a structure snopick of non-markable elements (target, meridian and 
-//  parallel).// 
-
-  Pres = theTPres;
-  Handle(V3d_Viewer) TheViewer = theView->Viewer();
-  if (!myGraphicStructure.IsNull()) {
-    myGraphicStructure->Disconnect(myGraphicStructure1);
-    myGraphicStructure->Clear();
-    myGraphicStructure1->Clear();
-    if (Pres == V3d_SAMELAST) Pres = myTypeOfRepresentation;
-  }
-  else {
-    if (Pres == V3d_SAMELAST) Pres = V3d_SIMPLE;
-    Handle(Graphic3d_Structure) slight = new Graphic3d_Structure(TheViewer->StructureManager());
-    myGraphicStructure = slight;
-    Handle(Graphic3d_Structure) snopick = new Graphic3d_Structure(TheViewer->StructureManager()); 
-    myGraphicStructure1 = snopick;
-  }
-
-  Handle(Graphic3d_Group) gradius, gExtArrow, gIntArrow;
-  if (Pres == V3d_COMPLETE)
-  {
-    gradius   = myGraphicStructure->NewGroup();
-    gExtArrow = myGraphicStructure->NewGroup();
-    gIntArrow = myGraphicStructure->NewGroup();
-  }
-  Handle(Graphic3d_Group) glight = myGraphicStructure->NewGroup();
-  Handle(Graphic3d_Group) gsphere;
-  if (Pres == V3d_COMPLETE
-   || Pres == V3d_PARTIAL)
-  {
-    gsphere = myGraphicStructure->NewGroup();
-  }
-  
-  Handle(Graphic3d_Group) gnopick = myGraphicStructure1->NewGroup();
-  
-  X0 = myTarget.X();
-  Y0 = myTarget.Y();
-  Z0 = myTarget.Z();
-  
-//Display of the position of the light.
-
-  const Quantity_Color Col1 = this->Color();
-  Handle(Graphic3d_AspectLine3d) Asp1 = new Graphic3d_AspectLine3d();
-  Asp1->SetColor(Col1);
-  glight->SetPrimitivesAspect(Asp1);
-  this->Symbol(glight,theView);
-  
-// Display of the reference sphere (limited by circle).
-
-  if (Pres == V3d_COMPLETE || Pres == V3d_PARTIAL) {
-    
-    Rayon = this->Radius(); 
-    theView->Proj(VX,VY,VZ);
-    V3d::CircleInPlane(gsphere,X0,Y0,Z0,VX,VY,VZ,Rayon);
-
-// Display of the radius of the sphere (line + text)
-
-    if (Pres == V3d_COMPLETE) {
-      this->Position(X,Y,Z);
-      Handle(Graphic3d_ArrayOfSegments) aPrims = new Graphic3d_ArrayOfSegments(2);
-      aPrims->AddVertex(X0,Y0,Z0);
-      aPrims->AddVertex(X,Y,Z);
-      gnopick->AddPrimitiveArray(aPrims);
-      V3d::ArrowOfRadius(gExtArrow,X-.1*(X-X0),Y-.1*(Y-Y0),Z-.1*(Z-Z0),X-X0,Y-Y0,Z-Z0,M_PI/15.,Rayon/20.);
-      V3d::ArrowOfRadius(gIntArrow,X0,Y0,Z0,X0-X,Y0-Y,Z0-Z,M_PI/15.,Rayon/20.);
-      TCollection_AsciiString ValOfRadius(Rayon);
-      Graphic3d_Vertex PText ( .5*(X0+X), .5*(Y0+Y), .5*(Z0+Z) );
-      gradius->Text(ValOfRadius.ToCString(),PText,0.01);
-    }
-    
-// Display of the meridian
-
-    Quantity_Color Col2(Quantity_NOC_GREEN);
-    Handle(Graphic3d_AspectLine3d) Asp2 = new Graphic3d_AspectLine3d(Col2,Aspect_TOL_SOLID,1.);
-    gnopick->SetPrimitivesAspect(Asp2);
-    
-//    Definition of the axis of the circle
-    theView->Up(DXRef,DYRef,DZRef);
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-
-//    Display of the parallel
-
-//    Definition of the axis of the circle
-    theView->Proj(VX,VY,VZ);
-    theView->Up(X1,Y1,Z1);
-    DXRef = VY * Z1 - VZ * Y1;
-    DYRef = VZ * X1 - VX * Z1;
-    DZRef = VX * Y1 - VY * X1;
-    this->Position(X,Y,Z);
-    DXini = X-X0; DYini = Y-Y0; DZini = Z-Z0;
-    VX = DYRef*DZini - DZRef*DYini;
-    VY = DZRef*DXini - DXRef*DZini;
-    VZ = DXRef*DYini - DYRef*DXini;
-    
-    V3d::CircleInPlane(gnopick,X0,Y0,Z0,VX,VY,VZ,Rayon);
-  }
-  
-  myGraphicStructure->Connect(myGraphicStructure1,Graphic3d_TOC_DESCENDANT);
-  myTypeOfRepresentation = Pres;
-  myGraphicStructure->Display();
+  SetDirection (V3d::GetProjAxis (theDirection));
 }
index 65fe287..8d1de06 100644 (file)
 #include <V3d_PositionLight.hxx>
 #include <V3d_TypeOfOrientation.hxx>
 
-class V3d_Viewer;
-class V3d_SpotLight;
-DEFINE_STANDARD_HANDLE(V3d_SpotLight, V3d_PositionLight)
-
 //! Creation and modification of a spot.
+//! The attenuation factor F determines the illumination of a surface:
+//! @code
+//!   F = 1/(ConstAttenuation() + LinearAttenuation() * Distance)
+//! @endcode
+//! Where Distance is the distance from the source to the surface.
+//! The default values (1.0, 0.0) correspond to a minimum of attenuation.
+//! The concentration factor determines the dispersion of the light on the surface, the default value (1.0) corresponds to a minimum of dispersion.
 class V3d_SpotLight : public V3d_PositionLight
 {
+  DEFINE_STANDARD_RTTIEXT(V3d_SpotLight, V3d_PositionLight)
 public:
 
-  //! Creates a light source of the Spot type in the viewer.
-  //! The attenuation factor F which determines
-  //! the illumination of a surface depends on the following formula :
-  //! F = 1/(theConstAttenuation + theLinearAttenuation*Length)
-  //! Length is the distance from the source to the surface.
-  //! The default values (1.0,0.0) correspond to a minimum
-  //! of attenuation.
-  //! The concentration factor determines the dispersion
-  //! of the light on the surface, the default value
-  //! (1.0) corresponds to a minimum of dispersion.
-  //! Warning! raises BadValue from V3d  -
-  //! If one of the coefficients is not between 0 and 1.
-  //! If the lighting angle is <= 0 or > PI.
+  //! Creates a light source of the Spot type in the viewer with default attenuation factors (1.0, 0.0),
+  //! concentration factor 1.0 and spot angle 30 degrees.
+  Standard_EXPORT V3d_SpotLight (const gp_Pnt& thePos,
+                                 const V3d_TypeOfOrientation theDirection = V3d_XnegYnegZpos,
+                                 const Quantity_Color& theColor = Quantity_NOC_WHITE);
+
+  //! Creates a light source of the Spot type in the viewer with default attenuation factors (1.0, 0.0),
+  //! concentration factor 1.0 and spot angle 30 degrees.
+  Standard_EXPORT V3d_SpotLight (const gp_Pnt& thePos,
+                                 const gp_Dir& theDirection,
+                                 const Quantity_Color& theColor = Quantity_NOC_WHITE);
+
+  //! Defines the direction of the light source
+  //! according to a predefined directional vector.
+  Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theOrientation);
+  using Graphic3d_CLight::SetDirection;
+  using Graphic3d_CLight::Position;
+  using Graphic3d_CLight::SetPosition;
+
+public:
+
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_SpotLight (const Handle(V3d_Viewer)& theViewer,
                                  const Standard_Real theX,
                                  const Standard_Real theY,
@@ -53,13 +66,9 @@ public:
                                  const Standard_Real theConcentration = 1.0,
                                  const Standard_Real theAngle = 0.523599);
   
-  //! Creates a light source of the Spot type in the viewer.
   //! theXt, theYt, theZt : Coordinate of light source Target.
   //! theXp, theYp, theZp : Coordinate of light source Position.
-  //! The others parameters describe before.
-  //! Warning! raises BadValue from V3d  -
-  //! If one of the coefficients is not between 0 and 1.
-  //! If the lighting angle is <= 0 or > PI.
+  Standard_DEPRECATED("This constructor is deprecated - the light source should be added to V3d_Viewer explicitly by method V3d_Viewer::AddLight()")
   Standard_EXPORT V3d_SpotLight (const Handle(V3d_Viewer)& theViewer,
                                  const Standard_Real theXt,
                                  const Standard_Real theYt,
@@ -73,99 +82,8 @@ public:
                                  const Standard_Real theConcentration = 1.0,
                                  const Standard_Real theAngle = 0.523599);
 
-  //! Defines the position of the light source.
-  virtual void SetPosition (Standard_Real theX,
-                            Standard_Real theY,
-                            Standard_Real theZ) Standard_OVERRIDE
-  {
-    myLight.Position.x() = theX;
-    myLight.Position.y() = theY;
-    myLight.Position.z() = theZ;
-  }
-
-  //! Defines the direction of the light source.
-  //! If the normal vector is NULL.
-  void SetDirection (Standard_Real theVx,
-                     Standard_Real theVy,
-                     Standard_Real theVz)
-  {
-    myLight.Direction.x() = static_cast<Standard_ShortReal> (theVx);
-    myLight.Direction.y() = static_cast<Standard_ShortReal> (theVy);
-    myLight.Direction.z() = static_cast<Standard_ShortReal> (theVz);
-  }
-
-  //! Defines the direction of the light source
-  //! according to a predefined directional vector.
-  Standard_EXPORT void SetDirection (V3d_TypeOfOrientation theOrientation);
-
-  //! Defines the coefficients of attenuation.
-  //! Warning! raises BadValue from V3d
-  //! if one of the coefficient is < 0 or > 1.
-  Standard_EXPORT void SetAttenuation (const Standard_Real theConstAttenuation,
-                                       const Standard_Real theLinearAttenuation);
-
-  //! Defines the coefficient of concentration.
-  //! if the coefficient is < 0 or > 1.
-  Standard_EXPORT void SetConcentration (const Standard_Real theConcentration);
-
-  //! Defines the spot angle in RADIANS.
-  //! Warning: raises BadValue from from V3d
-  //! If the angle is <= 0 or > PI.
-  Standard_EXPORT void SetAngle (const Standard_Real theAngle);
-
-  //! Display the graphic structure of light source
-  //! in the chosen view. We have three type of representation
-  //! - SIMPLE   : Only the light source is displayed.
-  //! - PARTIAL  : The light source and the light space are
-  //! displayed.
-  //! - COMPLETE : The light source, the light space and the
-  //! radius of light space are displayed.
-  //! We can choose the "SAMELAST" as parameter of representation
-  //! In this case the graphic structure representation will be
-  //! the last displayed.
-  Standard_EXPORT void Display (const Handle(V3d_View)& theView,
-                                const V3d_TypeOfRepresentation theRepresentation) Standard_OVERRIDE;
-
-  //! Returns the direction of the light source defined by theVx, theVy, theVz.
-  void Direction (Standard_Real& theVx,
-                  Standard_Real& theVy,
-                  Standard_Real& theVz) const
-  {
-    theVx = myLight.Direction.x();
-    theVy = myLight.Direction.y();
-    theVz = myLight.Direction.z();
-  }
-
-  //! Returns the position of the light source.
-  virtual void Position (Standard_Real& theX,
-                         Standard_Real& theY,
-                         Standard_Real& theZ) const Standard_OVERRIDE
-  {
-    theX = myLight.Position.x();
-    theY = myLight.Position.y();
-    theZ = myLight.Position.z();
-  }
-
-  //! Returns the attenuation factors A1,A2 of the light source.
-  void Attenuation (Standard_Real& theConstAttentuation,
-                    Standard_Real& theLinearAttentuation) const
-  {
-    theConstAttentuation  = myLight.ConstAttenuation();
-    theLinearAttentuation = myLight.LinearAttenuation();
-  }
-
-  Standard_Real Concentration() const { return myLight.Concentration(); }
-
-  //! Returns the spot angle.
-  Standard_Real Angle() const { return myLight.Angle(); }
-
-  DEFINE_STANDARD_RTTIEXT(V3d_SpotLight,V3d_PositionLight)
-
-private:
-
-  //! Defines the representation of the spot light source.
-  Standard_EXPORT void Symbol (const Handle(Graphic3d_Group)& theSymbol,
-                               const Handle(V3d_View)& theView) const Standard_OVERRIDE;
 };
 
+DEFINE_STANDARD_HANDLE(V3d_SpotLight, V3d_PositionLight)
+
 #endif // _V3d_SpotLight_HeaderFile
index cefb25d..4ae6acb 100644 (file)
 #ifndef _V3d_TypeOfLight_HeaderFile
 #define _V3d_TypeOfLight_HeaderFile
 
-//! Determines the type of light.
-enum V3d_TypeOfLight
-{
-V3d_AMBIENT,
-V3d_DIRECTIONAL,
-V3d_POSITIONAL,
-V3d_SPOT
-};
+#include <Graphic3d_TypeOfLightSource.hxx>
+
+typedef Graphic3d_TypeOfLightSource V3d_TypeOfLight;
 
 #endif // _V3d_TypeOfLight_HeaderFile
index ae5bed8..250739e 100644 (file)
@@ -377,10 +377,10 @@ Standard_Boolean V3d_View::IsEmpty() const
 //=============================================================================
 void V3d_View::UpdateLights() const
 {
-  Graphic3d_ListOfCLight aLights;
+  Handle(Graphic3d_LightSet) aLights = new Graphic3d_LightSet();
   for (V3d_ListOfLight::Iterator anActiveLightIter (myActiveLights); anActiveLightIter.More(); anActiveLightIter.Next())
   {
-    aLights.Append (anActiveLightIter.Value()->Light());
+    aLights->Add (anActiveLightIter.Value());
   }
   myView->SetLights (aLights);
 }
index 02b76de..60afb3e 100644 (file)
@@ -77,7 +77,6 @@ class Graphic3d_TextureEnv;
 class Standard_MultiplyDefined;
 class Standard_TypeMismatch;
 class V3d_BadValue;
-class V3d_Light;
 class V3d_UnMapped;
 
 class V3d_View;
index d2c5798..8c5db1e 100644 (file)
@@ -457,6 +457,10 @@ void V3d_Viewer::SetDefaultLights()
     DelLight (aLight);
   }
 
-  SetLightOn (new V3d_DirectionalLight (this, V3d_Zneg, Quantity_NOC_WHITE, Standard_True));
-  SetLightOn (new V3d_AmbientLight (this));
+  Handle(V3d_DirectionalLight) aDirLight  = new V3d_DirectionalLight (V3d_Zneg, Quantity_NOC_WHITE, Standard_True);
+  Handle(V3d_AmbientLight)     anAmbLight = new V3d_AmbientLight (Quantity_NOC_WHITE);
+  AddLight (aDirLight);
+  AddLight (anAmbLight);
+  SetLightOn (aDirLight);
+  SetLightOn (anAmbLight);
 }
index ab3d529..11a56c2 100644 (file)
@@ -59,7 +59,6 @@ class Graphic3d_Group;
 class Graphic3d_Structure;
 class V3d_BadValue;
 class V3d_CircularGrid;
-class V3d_Light;
 class V3d_RectangularGrid;
 class V3d_View;
 class Quantity_Color;
@@ -71,7 +70,6 @@ class Quantity_Color;
 class V3d_Viewer : public Standard_Transient
 {
   friend class V3d_View;
-  friend class V3d_Light;
   DEFINE_STANDARD_RTTIEXT(V3d_Viewer, Standard_Transient)
 public:
 
@@ -258,7 +256,10 @@ public: //! @name lights management
   
   //! Deactivate all the Lights defined in this viewer.
   Standard_EXPORT void SetLightOff();
-  
+
+  //! Adds Light in Sequence Of Lights.
+  Standard_EXPORT void AddLight (const Handle(V3d_Light)& theLight);
+
   //! Delete Light in Sequence Of Lights.
   Standard_EXPORT void DelLight (const Handle(V3d_Light)& theLight);
   
@@ -457,9 +458,6 @@ private:
   //! Delete View in Sequence Of Views.
   Standard_EXPORT void DelView (const Handle(V3d_View)& theView);
   
-  //! Adds Light in Sequence Of Lights.
-  Standard_EXPORT void AddLight (const Handle(V3d_Light)& theLight);
-  
 private:
 
   Handle(Graphic3d_GraphicDriver) myDriver;
index a8f65a7..6069f55 100644 (file)
@@ -9213,6 +9213,7 @@ static int VDefaults (Draw_Interpretor& theDi,
 
 //! Auxiliary method
 inline void addLight (const Handle(V3d_Light)& theLightNew,
+                      const Graphic3d_ZLayerId theLayer,
                       const Standard_Boolean   theIsGlobal)
 {
   if (theLightNew.IsNull())
@@ -9220,13 +9221,28 @@ inline void addLight (const Handle(V3d_Light)& theLightNew,
     return;
   }
 
-  if (theIsGlobal)
+  Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
+  if (theLayer == Graphic3d_ZLayerId_UNKNOWN)
   {
-    ViewerTest::GetViewerFromContext()->SetLightOn (theLightNew);
+    aViewer->AddLight (theLightNew);
+    if (theIsGlobal)
+    {
+      aViewer->SetLightOn (theLightNew);
+    }
+    else
+    {
+      ViewerTest::CurrentView()->SetLightOn (theLightNew);
+    }
   }
   else
   {
-    ViewerTest::CurrentView()->SetLightOn (theLightNew);
+    Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (theLayer);
+    if (aSettings.Lights().IsNull())
+    {
+      aSettings.SetLights (new Graphic3d_LightSet());
+    }
+    aSettings.Lights()->Add (theLightNew);
+    aViewer->SetZLayerSettings (theLayer, aSettings);
   }
 }
 
@@ -9273,7 +9289,9 @@ static int VLight (Draw_Interpretor& theDi,
     {
       Handle(V3d_Light) aLight = aLightIter.Value();
       const Quantity_Color aColor = aLight->Color();
-      theDi << "Light" << aLightId << "\n";
+      theDi << "Light #" << aLightId
+            << (!aLight->Name().IsEmpty() ? (TCollection_AsciiString(" ") + aLight->Name()) : "")
+            << " [" << aLight->GetId() << "]" << "\n";
       switch (aLight->Type())
       {
         case V3d_AMBIENT:
@@ -9284,53 +9302,39 @@ static int VLight (Draw_Interpretor& theDi,
         }
         case V3d_DIRECTIONAL:
         {
-          Handle(V3d_DirectionalLight) aLightDir = Handle(V3d_DirectionalLight)::DownCast (aLight);
           theDi << "  Type:       Directional\n";
           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
           theDi << "  Smoothness: " << aLight->Smoothness() << "\n";
-          if (!aLightDir.IsNull())
-          {
-            aLightDir->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
-            theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
-            aLightDir->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
-            theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
-          }
+          aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
+          theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
           break;
         }
         case V3d_POSITIONAL:
         {
-          Handle(V3d_PositionalLight) aLightPos = Handle(V3d_PositionalLight)::DownCast (aLight);
           theDi << "  Type:       Positional\n";
           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
           theDi << "  Smoothness: " << aLight->Smoothness() << "\n";
-          if (!aLightPos.IsNull())
-          {
-            aLightPos->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
-            theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
-            aLightPos->Attenuation (anAtten[0], anAtten[1]);
-            theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
-          }
+          aLight->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
+          theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+          aLight->Attenuation (anAtten[0], anAtten[1]);
+          theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
           break;
         }
         case V3d_SPOT:
         {
-          Handle(V3d_SpotLight) aLightSpot = Handle(V3d_SpotLight)::DownCast (aLight);
           theDi << "  Type:       Spot\n";
           theDi << "  Intensity:  " << aLight->Intensity() << "\n";
           theDi << "  Headlight:  " << (aLight->Headlight() ? "TRUE" : "FALSE") << "\n";
-          if (!aLightSpot.IsNull())
-          {
-            aLightSpot->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
-            theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
-            aLightSpot->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
-            theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
-            aLightSpot->Attenuation (anAtten[0], anAtten[1]);
-            theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
-            theDi << "  Angle:      " << (aLightSpot->Angle() * 180.0 / M_PI) << "\n";
-            theDi << "  Exponent:   " << aLightSpot->Concentration() << "\n";
-          }
+          aLight->Position  (anXYZ[0], anXYZ[1], anXYZ[2]);
+          theDi << "  Position:   " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+          aLight->Direction (anXYZ[0], anXYZ[1], anXYZ[2]);
+          theDi << "  Direction:  " << anXYZ[0] << ", " << anXYZ[1] << ", " << anXYZ[2] << "\n";
+          aLight->Attenuation (anAtten[0], anAtten[1]);
+          theDi << "  Atten.:     " << anAtten[0] << " " << anAtten[1] << "\n";
+          theDi << "  Angle:      " << (aLight->Angle() * 180.0 / M_PI) << "\n";
+          theDi << "  Exponent:   " << aLight->Concentration() << "\n";
           break;
         }
         default:
@@ -9339,22 +9343,19 @@ static int VLight (Draw_Interpretor& theDi,
           break;
         }
       }
-      theDi << "  Color:     " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << "\n";
+      theDi << "  Color:      " << aColor.Red() << ", " << aColor.Green() << ", " << aColor.Blue() << " [" << Quantity_Color::StringName (aColor.Name()) << "]\n";
     }
   }
 
   Handle(V3d_Light) aLightNew;
   Handle(V3d_Light) aLightOld;
+  Graphic3d_ZLayerId aLayer = Graphic3d_ZLayerId_UNKNOWN;
   Standard_Boolean  isGlobal = Standard_True;
   Standard_Boolean  toCreate = Standard_False;
   ViewerTest_AutoUpdater anUpdateTool (ViewerTest::GetAISContext(), aView);
   for (Standard_Integer anArgIt = 1; anArgIt < theArgsNb; ++anArgIt)
   {
-    Handle(V3d_Light)            aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
-    Handle(V3d_AmbientLight)     aLightAmb  = Handle(V3d_AmbientLight)    ::DownCast (aLightCurr);
-    Handle(V3d_DirectionalLight) aLightDir  = Handle(V3d_DirectionalLight)::DownCast (aLightCurr);
-    Handle(V3d_PositionalLight)  aLightPos  = Handle(V3d_PositionalLight) ::DownCast (aLightCurr);
-    Handle(V3d_SpotLight)        aLightSpot = Handle(V3d_SpotLight)       ::DownCast (aLightCurr);
+    Handle(V3d_Light) aLightCurr = aLightNew.IsNull() ? aLightOld : aLightNew;
 
     TCollection_AsciiString aName, aValue;
     const TCollection_AsciiString anArg (theArgVec[anArgIt]);
@@ -9367,96 +9368,177 @@ static int VLight (Draw_Interpretor& theDi,
 
     if (anArgCase.IsEqual ("NEW")
      || anArgCase.IsEqual ("ADD")
-     || anArgCase.IsEqual ("CREATE"))
+     || anArgCase.IsEqual ("CREATE")
+     || anArgCase.IsEqual ("-NEW")
+     || anArgCase.IsEqual ("-ADD")
+     || anArgCase.IsEqual ("-CREATE"))
     {
       toCreate = Standard_True;
     }
+    else if (anArgCase.IsEqual ("-LAYER")
+          || anArgCase.IsEqual ("-ZLAYER"))
+    {
+      if (++anArgIt >= theArgsNb)
+      {
+        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
+        return 1;
+      }
+
+      TCollection_AsciiString aValStr (theArgVec[anArgIt]);
+      aValStr.LowerCase();
+      if (aValStr == "default"
+       || aValStr == "def")
+      {
+        aLayer = Graphic3d_ZLayerId_Default;
+      }
+      else if (aValStr == "top")
+      {
+        aLayer = Graphic3d_ZLayerId_Top;
+      }
+      else if (aValStr == "topmost")
+      {
+        aLayer = Graphic3d_ZLayerId_Topmost;
+      }
+      else if (aValStr == "toposd"
+            || aValStr == "osd")
+      {
+        aLayer = Graphic3d_ZLayerId_TopOSD;
+      }
+      else if (aValStr == "botosd"
+            || aValStr == "bottom")
+      {
+        aLayer = Graphic3d_ZLayerId_BotOSD;
+      }
+      else if (aValStr.IsIntegerValue())
+      {
+        aLayer = Draw::Atoi (theArgVec[anArgIt]);
+      }
+      else
+      {
+        std::cout << "Wrong syntax at argument '" << anArg << "'!\n";
+        return 1;
+      }
+    }
     else if (anArgCase.IsEqual ("GLOB")
-          || anArgCase.IsEqual ("GLOBAL"))
+          || anArgCase.IsEqual ("GLOBAL")
+          || anArgCase.IsEqual ("-GLOB")
+          || anArgCase.IsEqual ("-GLOBAL"))
     {
       isGlobal = Standard_True;
     }
     else if (anArgCase.IsEqual ("LOC")
-          || anArgCase.IsEqual ("LOCAL"))
+          || anArgCase.IsEqual ("LOCAL")
+          || anArgCase.IsEqual ("-LOC")
+          || anArgCase.IsEqual ("-LOCAL"))
     {
       isGlobal = Standard_False;
     }
     else if (anArgCase.IsEqual ("DEF")
-          || anArgCase.IsEqual ("DEFAULTS"))
+          || anArgCase.IsEqual ("DEFAULTS")
+          || anArgCase.IsEqual ("-DEF")
+          || anArgCase.IsEqual ("-DEFAULTS"))
     {
       toCreate = Standard_False;
       aViewer->SetDefaultLights();
     }
     else if (anArgCase.IsEqual ("CLR")
-          || anArgCase.IsEqual ("CLEAR"))
+          || anArgCase.IsEqual ("CLEAR")
+          || anArgCase.IsEqual ("-CLR")
+          || anArgCase.IsEqual ("-CLEAR"))
     {
       toCreate = Standard_False;
-      for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
+
+      TColStd_SequenceOfInteger aLayers;
+      aViewer->GetAllZLayers (aLayers);
+      for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
       {
-        Handle(V3d_Light) aLight = aLightIter.Value();
-        aViewer->DelLight (aLight);
-        aLightIter = aView->ActiveLightIterator();
+        if (aLayeriter.Value() == aLayer
+         || aLayer == Graphic3d_ZLayerId_UNKNOWN)
+        {
+          Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
+          aSettings.SetLights (Handle(Graphic3d_LightSet)());
+          aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
+          if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
+          {
+            break;
+          }
+        }
+      }
+
+      if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
+      {
+        for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More();)
+        {
+          Handle(V3d_Light) aLight = aLightIter.Value();
+          aViewer->DelLight (aLight);
+          aLightIter = aView->ActiveLightIterator();
+        }
       }
     }
     else if (anArgCase.IsEqual ("AMB")
           || anArgCase.IsEqual ("AMBIENT")
           || anArgCase.IsEqual ("AMBLIGHT"))
     {
-      addLight (aLightNew, isGlobal);
       if (!toCreate)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
+
+      addLight (aLightNew, aLayer, isGlobal);
       toCreate  = Standard_False;
-      aLightNew = new V3d_AmbientLight (aViewer);
+      aLightNew = new V3d_AmbientLight();
     }
     else if (anArgCase.IsEqual ("DIRECTIONAL")
           || anArgCase.IsEqual ("DIRLIGHT"))
     {
-      addLight (aLightNew, isGlobal);
       if (!toCreate)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
+
+      addLight (aLightNew, aLayer, isGlobal);
       toCreate  = Standard_False;
-      aLightNew = new V3d_DirectionalLight (aViewer);
+      aLightNew = new V3d_DirectionalLight();
     }
     else if (anArgCase.IsEqual ("SPOT")
           || anArgCase.IsEqual ("SPOTLIGHT"))
     {
-      addLight (aLightNew, isGlobal);
       if (!toCreate)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
+
+      addLight (aLightNew, aLayer, isGlobal);
       toCreate  = Standard_False;
-      aLightNew = new V3d_SpotLight (aViewer, 0.0, 0.0, 0.0);
+      aLightNew = new V3d_SpotLight (gp_Pnt (0.0, 0.0, 0.0));
     }
     else if (anArgCase.IsEqual ("POSLIGHT")
           || anArgCase.IsEqual ("POSITIONAL"))
     {
-      addLight (aLightNew, isGlobal);
       if (!toCreate)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
+
+      addLight (aLightNew, aLayer, isGlobal);
       toCreate  = Standard_False;
-      aLightNew = new V3d_PositionalLight (aViewer, 0.0, 0.0, 0.0);
+      aLightNew = new V3d_PositionalLight (gp_Pnt (0.0, 0.0, 0.0));
     }
-    else if (anArgCase.IsEqual ("CHANGE"))
+    else if (anArgCase.IsEqual ("CHANGE")
+          || anArgCase.IsEqual ("-CHANGE"))
     {
-      addLight (aLightNew, isGlobal);
-      aLightNew.Nullify();
       if (++anArgIt >= theArgsNb)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
+      addLight (aLightNew, aLayer, isGlobal);
+      aLightNew.Nullify();
       const Standard_Integer aLightId = getLightId (theArgVec[anArgIt]);
       Standard_Integer aLightIt = 0;
       for (V3d_ListOfLightIterator aLightIter (aView->ActiveLightIterator()); aLightIter.More(); aLightIter.Next(), ++aLightIt)
@@ -9475,7 +9557,9 @@ static int VLight (Draw_Interpretor& theDi,
       }
     }
     else if (anArgCase.IsEqual ("DEL")
-          || anArgCase.IsEqual ("DELETE"))
+          || anArgCase.IsEqual ("DELETE")
+          || anArgCase.IsEqual ("-DEL")
+          || anArgCase.IsEqual ("-DELETE"))
     {
       Handle(V3d_Light) aLightDel;
       if (++anArgIt >= theArgsNb)
@@ -9495,15 +9579,47 @@ static int VLight (Draw_Interpretor& theDi,
           break;
         }
       }
-      if (!aLightDel.IsNull())
+      if (aLightDel.IsNull())
+      {
+        continue;
+      }
+
+      TColStd_SequenceOfInteger aLayers;
+      aViewer->GetAllZLayers (aLayers);
+      for (TColStd_SequenceOfInteger::Iterator aLayeriter (aLayers); aLayeriter.More(); aLayeriter.Next())
+      {
+        if (aLayeriter.Value() == aLayer
+         || aLayer == Graphic3d_ZLayerId_UNKNOWN)
+        {
+          Graphic3d_ZLayerSettings aSettings = aViewer->ZLayerSettings (aLayeriter.Value());
+          if (!aSettings.Lights().IsNull())
+          {
+            aSettings.Lights()->Remove (aLightDel);
+            if (aSettings.Lights()->IsEmpty())
+            {
+              aSettings.SetLights (Handle(Graphic3d_LightSet)());
+            }
+          }
+          aViewer->SetZLayerSettings (aLayeriter.Value(), aSettings);
+          if (aLayer != Graphic3d_ZLayerId_UNKNOWN)
+          {
+            break;
+          }
+        }
+      }
+
+      if (aLayer == Graphic3d_ZLayerId_UNKNOWN)
       {
         aViewer->DelLight (aLightDel);
       }
     }
     else if (anArgCase.IsEqual ("COLOR")
-          || anArgCase.IsEqual ("COLOUR"))
+          || anArgCase.IsEqual ("COLOUR")
+          || anArgCase.IsEqual ("-COLOR")
+          || anArgCase.IsEqual ("-COLOUR"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull())
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
@@ -9512,15 +9628,17 @@ static int VLight (Draw_Interpretor& theDi,
       TCollection_AsciiString anArgNext (theArgVec[anArgIt]);
       anArgNext.UpperCase();
       const Quantity_Color aColor = ViewerTest::GetColorFromName (anArgNext.ToCString());
-      if (!aLightCurr.IsNull())
-      {
-        aLightCurr->SetColor (aColor);
-      }
+      aLightCurr->SetColor (aColor);
     }
     else if (anArgCase.IsEqual ("POS")
-          || anArgCase.IsEqual ("POSITION"))
+          || anArgCase.IsEqual ("POSITION")
+          || anArgCase.IsEqual ("-POS")
+          || anArgCase.IsEqual ("-POSITION"))
     {
-      if ((anArgIt + 3) >= theArgsNb)
+      if ((anArgIt + 3) >= theArgsNb
+       || aLightCurr.IsNull()
+       || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
+        && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
@@ -9529,28 +9647,17 @@ static int VLight (Draw_Interpretor& theDi,
       anXYZ[0] = Atof (theArgVec[++anArgIt]);
       anXYZ[1] = Atof (theArgVec[++anArgIt]);
       anXYZ[2] = Atof (theArgVec[++anArgIt]);
-      if (!aLightDir.IsNull())
-      {
-        aLightDir->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
-      }
-      else if (!aLightPos.IsNull())
-      {
-        aLightPos->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
-      }
-      else if (!aLightSpot.IsNull())
-      {
-        aLightSpot->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
-      }
-      else
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
+      aLightCurr->SetPosition (anXYZ[0], anXYZ[1], anXYZ[2]);
     }
     else if (anArgCase.IsEqual ("DIR")
-          || anArgCase.IsEqual ("DIRECTION"))
+          || anArgCase.IsEqual ("DIRECTION")
+          || anArgCase.IsEqual ("-DIR")
+          || anArgCase.IsEqual ("-DIRECTION"))
     {
-      if ((anArgIt + 3) >= theArgsNb)
+      if ((anArgIt + 3) >= theArgsNb
+       || aLightCurr.IsNull()
+       || (aLightCurr->Type() != Graphic3d_TOLS_DIRECTIONAL
+        && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
@@ -9559,36 +9666,26 @@ static int VLight (Draw_Interpretor& theDi,
       anXYZ[0] = Atof (theArgVec[++anArgIt]);
       anXYZ[1] = Atof (theArgVec[++anArgIt]);
       anXYZ[2] = Atof (theArgVec[++anArgIt]);
-      if (!aLightDir.IsNull())
-      {
-        aLightDir->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
-      }
-      else if (!aLightSpot.IsNull())
-      {
-        aLightSpot->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
-      }
-      else
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
+      aLightCurr->SetDirection (anXYZ[0], anXYZ[1], anXYZ[2]);
     }
     else if (anArgCase.IsEqual ("SM")
-          || anArgCase.IsEqual ("SMOOTHNESS"))
+          || anArgCase.IsEqual ("SMOOTHNESS")
+          || anArgCase.IsEqual ("-SM")
+          || anArgCase.IsEqual ("-SMOOTHNESS"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull())
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      Standard_Real aSmoothness = Atof (theArgVec[anArgIt]);
-
-      if (fabs (aSmoothness) < Precision::Confusion())
+      Standard_ShortReal aSmoothness = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
+      if (Abs (aSmoothness) <= ShortRealEpsilon())
       {
         aLightCurr->SetIntensity (1.f);
       }
-      else if (fabs (aLightCurr->Smoothness()) < Precision::Confusion())
+      else if (Abs (aLightCurr->Smoothness()) <= ShortRealEpsilon())
       {
         aLightCurr->SetIntensity ((aSmoothness * aSmoothness) / 3.f);
       }
@@ -9598,142 +9695,122 @@ static int VLight (Draw_Interpretor& theDi,
         aLightCurr->SetIntensity (aLightCurr->Intensity() / (aSmoothnessRatio * aSmoothnessRatio));
       }
 
-      if (!aLightPos.IsNull())
+      if (aLightCurr->Type() == Graphic3d_TOLS_POSITIONAL)
       {
-        aLightPos->SetSmoothRadius (aSmoothness);
+        aLightCurr->SetSmoothRadius (aSmoothness);
       }
-      else if (!aLightDir.IsNull())
+      else if (aLightCurr->Type() == Graphic3d_TOLS_DIRECTIONAL)
       {
-        aLightDir->SetSmoothAngle (aSmoothness);
+        aLightCurr->SetSmoothAngle (aSmoothness);
       }
     }
     else if (anArgCase.IsEqual ("INT")
-          || anArgCase.IsEqual ("INTENSITY"))
+          || anArgCase.IsEqual ("INTENSITY")
+          || anArgCase.IsEqual ("-INT")
+          || anArgCase.IsEqual ("-INTENSITY"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull())
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      Standard_Real aIntensity = Atof (theArgVec[anArgIt]);
-
-      if (!aLightCurr.IsNull())
-      {
-        aLightCurr->SetIntensity (aIntensity);
-      }
+      Standard_ShortReal aIntensity = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
+      aLightCurr->SetIntensity (aIntensity);
     }
     else if (anArgCase.IsEqual ("ANG")
-          || anArgCase.IsEqual ("ANGLE"))
+          || anArgCase.IsEqual ("ANGLE")
+          || anArgCase.IsEqual ("-ANG")
+          || anArgCase.IsEqual ("-ANGLE"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull()
+       || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      Standard_Real anAngle = Atof (theArgVec[anArgIt]);
-
-      if (!aLightSpot.IsNull())
-      {
-        aLightSpot->SetAngle (anAngle / 180.0 * M_PI);
-      }
+      Standard_ShortReal anAngle = (Standard_ShortReal )Atof (theArgVec[anArgIt]);
+      aLightCurr->SetAngle (Standard_ShortReal (anAngle / 180.0 * M_PI));
     }
     else if (anArgCase.IsEqual ("CONSTATTEN")
-          || anArgCase.IsEqual ("CONSTATTENUATION"))
+          || anArgCase.IsEqual ("CONSTATTENUATION")
+          || anArgCase.IsEqual ("-CONSTATTEN")
+          || anArgCase.IsEqual ("-CONSTATTENUATION"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull()
+       || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
+        && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      if (!aLightPos.IsNull())
-      {
-        aLightPos->Attenuation (anAtten[0], anAtten[1]);
-        anAtten[0] = Atof (theArgVec[anArgIt]);
-        aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
-      }
-      else if (!aLightSpot.IsNull())
-      {
-        aLightSpot->Attenuation (anAtten[0], anAtten[1]);
-        anAtten[0] = Atof (theArgVec[anArgIt]);
-        aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
-      }
-      else
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
+      aLightCurr->Attenuation (anAtten[0], anAtten[1]);
+      anAtten[0] = Atof (theArgVec[anArgIt]);
+      aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
     }
     else if (anArgCase.IsEqual ("LINATTEN")
           || anArgCase.IsEqual ("LINEARATTEN")
-          || anArgCase.IsEqual ("LINEARATTENUATION"))
+          || anArgCase.IsEqual ("LINEARATTENUATION")
+          || anArgCase.IsEqual ("-LINATTEN")
+          || anArgCase.IsEqual ("-LINEARATTEN")
+          || anArgCase.IsEqual ("-LINEARATTENUATION"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull()
+       || (aLightCurr->Type() != Graphic3d_TOLS_POSITIONAL
+        && aLightCurr->Type() != Graphic3d_TOLS_SPOT))
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      if (!aLightPos.IsNull())
-      {
-        aLightPos->Attenuation (anAtten[0], anAtten[1]);
-        anAtten[1] = Atof (theArgVec[anArgIt]);
-        aLightPos->SetAttenuation (anAtten[0], anAtten[1]);
-      }
-      else if (!aLightSpot.IsNull())
-      {
-        aLightSpot->Attenuation (anAtten[0], anAtten[1]);
-        anAtten[1] = Atof (theArgVec[anArgIt]);
-        aLightSpot->SetAttenuation (anAtten[0], anAtten[1]);
-      }
-      else
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
+      aLightCurr->Attenuation (anAtten[0], anAtten[1]);
+      anAtten[1] = Atof (theArgVec[anArgIt]);
+      aLightCurr->SetAttenuation ((Standard_ShortReal )anAtten[0], (Standard_ShortReal )anAtten[1]);
     }
     else if (anArgCase.IsEqual ("EXP")
           || anArgCase.IsEqual ("EXPONENT")
           || anArgCase.IsEqual ("SPOTEXP")
-          || anArgCase.IsEqual ("SPOTEXPONENT"))
+          || anArgCase.IsEqual ("SPOTEXPONENT")
+          || anArgCase.IsEqual ("-EXP")
+          || anArgCase.IsEqual ("-EXPONENT")
+          || anArgCase.IsEqual ("-SPOTEXP")
+          || anArgCase.IsEqual ("-SPOTEXPONENT"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (++anArgIt >= theArgsNb
+       || aLightCurr.IsNull()
+       || aLightCurr->Type() != Graphic3d_TOLS_SPOT)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      if (!aLightSpot.IsNull())
-      {
-        aLightSpot->SetConcentration (Atof (theArgVec[anArgIt]));
-      }
-      else
-      {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
-      }
+      aLightCurr->SetConcentration ((Standard_ShortReal )Atof (theArgVec[anArgIt]));
     }
     else if (anArgCase.IsEqual ("HEAD")
-          || anArgCase.IsEqual ("HEADLIGHT"))
+          || anArgCase.IsEqual ("HEADLIGHT")
+          || anArgCase.IsEqual ("-HEAD")
+          || anArgCase.IsEqual ("-HEADLIGHT"))
     {
-      if (++anArgIt >= theArgsNb)
+      if (aLightCurr.IsNull()
+       || aLightCurr->Type() == Graphic3d_TOLS_AMBIENT)
       {
         std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
         return 1;
       }
 
-      if (aLightAmb.IsNull()
-       && !aLightCurr.IsNull())
-      {
-        aLightCurr->SetHeadlight (Draw::Atoi (theArgVec[anArgIt]) != 0);
-      }
-      else
+      Standard_Boolean isHeadLight = Standard_True;
+      if (anArgIt + 1 < theArgsNb
+       && ViewerTest::ParseOnOff (theArgVec[anArgIt + 1], isHeadLight))
       {
-        std::cerr << "Wrong syntax at argument '" << anArg << "'!\n";
-        return 1;
+        ++anArgIt;
       }
+      aLightCurr->SetHeadlight (isHeadLight);
     }
     else
     {
@@ -9741,9 +9818,7 @@ static int VLight (Draw_Interpretor& theDi,
     }
   }
 
-  addLight (aLightNew, isGlobal);
-  aViewer->UpdateLights();
-
+  addLight (aLightNew, aLayer, isGlobal);
   return 0;
 }
 
@@ -11930,25 +12005,26 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
   theCommands.Add("vlight",
     "tool to manage light sources, without arguments shows list of lights."
     "\n    Main commands: "
-    "\n      'clear' to clear lights"
-    "\n      '{def}aults' to load deafault lights"
-    "\n      'add' (or 'new') <type> to add any light source"
+    "\n      '-clear' to clear lights"
+    "\n      '-{def}aults' to load deafault lights"
+    "\n      '-add' <type> to add any light source"
     "\n          where <type> is one of {amb}ient|directional|{spot}light|positional"
     "\n      'change' <lightId> to edit light source with specified lightId"
     "\n\n      In addition to 'add' and 'change' commands you can use light parameters:"
-    "\n        {pos}ition X Y Z"
-    "\n        {dir}ection X Y Z (for directional light or for spotlight)"
-    "\n        color colorName"
-    "\n        {head}light 0|1"
-    "\n        {sm}oothness value"
-    "\n        {int}ensity value"
-    "\n        {constAtten}uation value"
-    "\n        {linearAtten}uation value"
-    "\n        angle angleDeg"
-    "\n        {spotexp}onent value"
-    "\n        local|global"
-    "\n\n        example: vlight add positional head 1 pos 0 1 1 color red"
-    "\n        example: vlight change 0 direction 0 -1 0 linearAttenuation 0.2",
+    "\n        -layer Id"
+    "\n        -{pos}ition X Y Z"
+    "\n        -{dir}ection X Y Z (for directional light or for spotlight)"
+    "\n        -color colorName"
+    "\n        -{head}light 0|1"
+    "\n        -{sm}oothness value"
+    "\n        -{int}ensity value"
+    "\n        -{constAtten}uation value"
+    "\n        -{linearAtten}uation value"
+    "\n        -angle angleDeg"
+    "\n        -{spotexp}onent value"
+    "\n        -local|-global"
+    "\n\n        example: vlight -add positional -head 1 -pos 0 1 1 -color red"
+    "\n        example: vlight -change 0 -direction 0 -1 0 -linearAttenuation 0.2",
     __FILE__, VLight, group);
   theCommands.Add("vraytrace",
             "vraytrace [0|1]"
index f8d2415..f3da39d 100644 (file)
@@ -23,12 +23,13 @@ vdisplay -dispMode 1 f1 f2
 vsetlocation f2 $anX 0.001 0
 vpoint vl $anX 0 0.001
 vfit
+vzbufftrihedron
 
 # setup light
 vcaps -ffp 0
 vrenderparams -shadingModel phong
-vlight clear
-vlight add positional pos $anX 0 0.001 color RED1 headLight 0
+vlight -layer default -clear
+vlight -layer default -add positional -pos $anX 0 0.001 -color RED1 -headLight 0
 
 set aColor1 [vreadpixel 205 180 rgb name]
 set aColor2 [vreadpixel 205 220 rgb name]
diff --git a/tests/v3d/glsl/phong_pos3 b/tests/v3d/glsl/phong_pos3
new file mode 100644 (file)
index 0000000..ad80e54
--- /dev/null
@@ -0,0 +1,46 @@
+puts "========"
+puts "0029290: Visualization, TKOpenGl - allow defining Light source per ZLayer"
+puts "========"
+
+pload MODELING VISUALIZATION
+
+vclear
+vclose ALL
+vinit View1 -width 1024 -height 768
+
+vaxo
+vcaps -ffp 0
+vrenderparams -shadingModel phong
+vlight clear
+
+set THE_LIGHTS {
+  { -1 -1 -1 RED1 }
+  {  1 -1 -1 YELLOW }
+  { -1  1 -1 BLUE1 }
+  { -1 -1  1 CYAN1 }
+  {  1  1 -1 PURPLE }
+  {  1  1  1 WHITE }
+  { -1  1  1 HOTPINK }
+  {  1 -1  1 GREEN }
+  {  0 -1  0 MAGENTA1 }
+  {  0  1  0 MAGENTA3 }
+}
+
+set aLayers [list [vzlayer -add -disable depthClear] [vzlayer -add -disable depthClear] [vzlayer -add -disable depthClear]]
+for { set aLayIter 0 } { $aLayIter < 3 } { incr aLayIter } {
+  set aLayer [lindex $aLayers $aLayIter]
+  set aShiftX [expr $aLayIter * 4]
+  psphere s$aLayer 0.5
+  vdisplay -dispMode 1 -layer $aLayer s$aLayer
+  vsetlocation s$aLayer $aShiftX 0 0
+  for { set aLightIter 0 } { $aLightIter < 10 } { incr aLightIter } {
+       set aLight [lindex $THE_LIGHTS $aLightIter]
+    set aColor [lindex $aLight 3]
+    set aPos [list [expr $aShiftX + [lindex $aLight 0]] [lindex $aLight 1] [lindex $aLight 2]]
+    vlight -layer $aLayer -add positional -pos {*}$aPos -color $aColor -headLight 0
+    vpoint v${aLayIter}_${aLightIter} {*}$aPos
+    vdrawtext t${aLayIter}_${aLightIter} "l${aLayIter}_${aLightIter} $aColor" -pos {*}$aPos -color $aColor
+  }
+}
+vfit
+vdump $::imagedir/${::casename}.png
diff --git a/tests/v3d/glsl/phong_pos4 b/tests/v3d/glsl/phong_pos4
new file mode 100644 (file)
index 0000000..6101ace
--- /dev/null
@@ -0,0 +1,35 @@
+puts "========"
+puts "0029283: Visualization - allow defining more than 8 light sources"
+puts "Test case creates about 100 of light sources."
+puts "========"
+
+pload MODELING VISUALIZATION
+
+vclear
+vclose ALL
+vinit View1
+vcaps -ffp 0
+vrenderparams -shadingModel phong
+box b -50 5 -50 100 100 100
+vdisplay -dispMode 1 b
+vfront
+vfit
+
+# define lights
+set THE_COLORS { RED1 YELLOW BLUE1 CYAN1 PURPLE WHITE HOTPINK GREEN MAGENTA1 MAGENTA3 }
+vlight clear
+set aNbColors 10
+set aLightIndex 0
+set aConstAtten 0.1
+set aLinAtten 1
+set aRand [expr srand(1)]
+for { set anZIter -50 } { $anZIter <= 50 } { set anZIter [expr $anZIter + 10] } {
+  for { set anXIter -50 } { $anXIter <= 50 } { set anXIter [expr $anXIter + 10] } {
+    set anIndex [expr {int(rand() * $aNbColors)}]
+    set aColor [lindex $THE_COLORS $anIndex]
+    set aPos "$anXIter 0 $anZIter"
+    vlight -add positional -pos {*}$aPos -color $aColor -headLight 0 -constAttenuation $aConstAtten -linearAttenuation $aLinAtten
+    vpoint v${aLightIndex} {*}$aPos
+    set aLightIndex [expr $aLightIndex + 1]
+  }
+}
index 7ae32e9..77300fc 100644 (file)
@@ -12,7 +12,7 @@ vglinfo
 vsetgradientbg 180 200 255 180 180 180 2
 
 # display shape
-vlight change 0 pos -1 1 1
+vlight -change 0 -dir 0.577 -0.577 -0.577
 restore $aShape s
 vsetdispmode 1
 vdisplay s
index f258d7a..66bb214 100644 (file)
@@ -19,7 +19,7 @@ vdisplay s1 s2
 vsetmaterial s1 Silver
 vsetmaterial s2 Pewter
 vsetlocation s1 0.0 0.1 0.0
-vlight change 0 pos -1 1 1
+vlight -change 0 -dir 0.577 -0.577 -0.577
 vfit
 
 # activate ray-tracing
index a6524bb..dbf3260 100644 (file)
@@ -37,7 +37,7 @@ vmarkerstest mTest 7 -3 0 PointsOnSide=5 MarkerType=5
 # 3d text
 vdrawtext text0 3D_Text -pos 1 2 2 -color 1.0 0.0 0.0 -halign left -valign bottom -angle 0 -zoom 0 -height 20 -aspect regular -font SansFont
 
-vlight change 0 pos -1 1 1
+vlight -change 0 -dir 0.577 -0.577 -0.577
 
 vfit
 
index 0696239..6ece710 100644 (file)
@@ -20,7 +20,7 @@ vdisplay s1 s2
 vsetmaterial s1 Gold
 vsetmaterial s2 Silver
 vsetlocation s1 0.0 0.1 0.0
-vlight change 0 pos -1 1 0.5
+vlight -change 0 -dir 0.667 -0.667 -0.333
 vturnview 3.0 -1.2 -0.1
 vfit
 
index cb5882a..dfd63de 100644 (file)
@@ -24,7 +24,7 @@ vdisplay s1 s2
 vsetmaterial s1 Silver
 vsetmaterial s2 Pewter
 vsetlocation s1 0.0 0.1 0.0
-vlight change 0 pos -1 1 1
+vlight -change 0 -dir 0.577 -0.577 -0.577
 
 # activate ray-tracing
 vrenderparams -raytrace
index c43452d..1576337 100644 (file)
@@ -70,6 +70,6 @@ vsettransparency B3 0.8
 vfront
 vturnview 0 -0.3 0
 vfit
-vlight change 0 pos 1 1 1
+vlight -change 0 -dir -0.577 -0.577 -0.577
 vlight add directional
 vrenderparams -raytrace -raydepth 5 -shadows off -reflections -fsaa
index 67dcc40..14da6f0 100644 (file)
@@ -70,6 +70,6 @@ vsetcolor wall2 green
 vfront
 vturnview 0 -0.3 0
 vfit
-vlight change 0 pos 1 1 1
+vlight -change 0 -dir -0.577 -0.577 -0.577
 vlight add directional
 vrenderparams -raytrace -raydepth 3 -shadows on -reflections -fsaa