0024070: OpenGL capped object-level clipping planes
authorapl <apl@opencascade.com>
Thu, 19 Sep 2013 12:58:00 +0000 (16:58 +0400)
committerbugmaster <bugmaster@opencascade.com>
Fri, 20 Sep 2013 08:09:54 +0000 (12:09 +0400)
Graphical clipping:
- Use "Graphic3d_ClipPlane" to defined clipping for PrsMgr_PresentableObject (local clipping), for V3d_View (global clipping).

Get rid of old implementations:
- Remove Visual3d_ClipPlane.
- Port V3d_Plane to Graphic3d_ClipPlane core.

Selection Sensitives:
- Port "Matches" method to add full set of arguments (SelectBasics_PickArgs), including min-max depth coming from selector.
- Get rid of transient data for pair Matches -> ComputeDepth.
- Extend SelectMgr_ViewerSelector::LoadResult to work with local clipping, add virtual callbacks to compute globa/local depth clipping for picking.

Capping rendering algorithm:
- Recursive rendering algorithm for OpenGl_Groups.
- Introduced Rendering filter for groups.

Clipping plane management in TKOpenGl:
- Added OpenGl_ClippingState to OpenGl_Context.

DRAWEXE commands:
- Ported "vclipplane" command for new approach.
- Added "vsettexturemode" command for changing texture details in views (enable / disable textures).

Correct DownCast syntax (compilation error)

Fix new compiler warnings

tests/bugs/vis/bug22906 migrated to the new vclipplane syntax

111 files changed:
src/AIS/AIS_InteractiveContext_2.cxx
src/Graphic3d/FILES
src/Graphic3d/Graphic3d.cdl
src/Graphic3d/Graphic3d_CPlane.hxx [deleted file]
src/Graphic3d/Graphic3d_CStructure.hxx
src/Graphic3d/Graphic3d_CView.hxx
src/Graphic3d/Graphic3d_ClipPlane.cxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ClipPlane.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_GraphicDriver.cdl
src/Graphic3d/Graphic3d_GraphicDriver.cxx
src/Graphic3d/Graphic3d_MarkerImage.cxx
src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx [new file with mode: 0644]
src/Graphic3d/Graphic3d_Structure.cdl
src/Graphic3d/Graphic3d_Structure.cxx
src/InterfaceGraphic/InterfaceGraphic_Visual3d.hxx
src/MeshVS/MeshVS_DummySensitiveEntity.cdl
src/MeshVS/MeshVS_DummySensitiveEntity.cxx
src/MeshVS/MeshVS_SensitiveMesh.cdl
src/MeshVS/MeshVS_SensitiveMesh.cxx
src/MeshVS/MeshVS_SensitivePolyhedron.cdl
src/MeshVS/MeshVS_SensitivePolyhedron.cxx
src/OpenGl/FILES
src/OpenGl/OpenGl_AspectFace.cxx
src/OpenGl/OpenGl_AspectFace.hxx
src/OpenGl/OpenGl_CappingAlgo.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_CappingAlgo.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_CappingPlaneResource.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_CappingPlaneResource.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_ClippingState.cxx [new file with mode: 0644]
src/OpenGl/OpenGl_ClippingState.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_Element.hxx
src/OpenGl/OpenGl_GraphicDriver.hxx
src/OpenGl/OpenGl_GraphicDriver_7.cxx
src/OpenGl/OpenGl_Group.cxx
src/OpenGl/OpenGl_Group.hxx
src/OpenGl/OpenGl_Matrix.hxx
src/OpenGl/OpenGl_RenderFilter.cxx [moved from src/Graphic3d/Graphic3d_CPlane.cxx with 77% similarity, mode: 0644]
src/OpenGl/OpenGl_RenderFilter.hxx [new file with mode: 0644]
src/OpenGl/OpenGl_Structure.cxx
src/OpenGl/OpenGl_Structure.hxx
src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_2.cxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/PrsMgr/PrsMgr_PresentableObject.cdl
src/PrsMgr/PrsMgr_PresentableObject.cxx
src/PrsMgr/PrsMgr_PresentableObject.lxx
src/QABugs/QABugs_3.cxx
src/Select3D/Select3D_Projector.cdl
src/Select3D/Select3D_Projector.cxx
src/Select3D/Select3D_Projector.lxx
src/Select3D/Select3D_SensitiveBox.cdl
src/Select3D/Select3D_SensitiveBox.cxx
src/Select3D/Select3D_SensitiveCircle.cdl
src/Select3D/Select3D_SensitiveCircle.cxx
src/Select3D/Select3D_SensitiveCurve.cdl
src/Select3D/Select3D_SensitiveCurve.cxx
src/Select3D/Select3D_SensitiveEntity.cdl
src/Select3D/Select3D_SensitiveEntity.cxx
src/Select3D/Select3D_SensitiveFace.cdl
src/Select3D/Select3D_SensitiveFace.cxx
src/Select3D/Select3D_SensitiveGroup.cdl
src/Select3D/Select3D_SensitiveGroup.cxx
src/Select3D/Select3D_SensitivePoint.cdl
src/Select3D/Select3D_SensitivePoint.cxx
src/Select3D/Select3D_SensitivePoly.cxx
src/Select3D/Select3D_SensitiveSegment.cdl
src/Select3D/Select3D_SensitiveSegment.cxx
src/Select3D/Select3D_SensitiveTriangle.cdl
src/Select3D/Select3D_SensitiveTriangle.cxx
src/Select3D/Select3D_SensitiveTriangulation.cdl
src/Select3D/Select3D_SensitiveTriangulation.cxx
src/Select3D/Select3D_SensitiveWire.cdl
src/Select3D/Select3D_SensitiveWire.cxx
src/SelectBasics/FILES [new file with mode: 0644]
src/SelectBasics/SelectBasics.cdl
src/SelectBasics/SelectBasics_PickArgs.hxx [new file with mode: 0644]
src/SelectBasics/SelectBasics_SensitiveEntity.cdl
src/SelectBasics/SelectBasics_SensitiveEntity.cxx
src/SelectMgr/FILES
src/SelectMgr/SelectMgr.cdl
src/SelectMgr/SelectMgr_ViewerSelector.cdl
src/SelectMgr/SelectMgr_ViewerSelector.cxx
src/StdSelect/StdSelect_ViewerSelector3d.cdl
src/StdSelect/StdSelect_ViewerSelector3d.cxx
src/V3d/FILES
src/V3d/V3d.cdl
src/V3d/V3d_Plane.cdl [deleted file]
src/V3d/V3d_Plane.cxx [changed mode: 0755->0644]
src/V3d/V3d_Plane.hxx [new file with mode: 0644]
src/V3d/V3d_View.cdl
src/V3d/V3d_View.cxx
src/V3d/V3d_View_2.cxx
src/V3d/V3d_Viewer.cdl
src/V3d/V3d_Viewer.cxx
src/V3d/V3d_Viewer_1.cxx
src/ViewerTest/ViewerTest.cdl
src/ViewerTest/ViewerTest_ObjectCommands.cxx
src/ViewerTest/ViewerTest_ViewerCommands.cxx
src/Visual3d/Visual3d.cdl
src/Visual3d/Visual3d_ClipPlane.cdl [deleted file]
src/Visual3d/Visual3d_ClipPlane.cxx [deleted file]
src/Visual3d/Visual3d_ContextView.cdl
src/Visual3d/Visual3d_ContextView.cxx
src/Visual3d/Visual3d_View.cdl
src/Visual3d/Visual3d_View.cxx
tests/bugs/vis/bug22906

index 4159a3b..198c5bd 100755 (executable)
@@ -140,7 +140,6 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index,
    if(updateproj)
      myMainSel->UpdateConversion();
    else{
-     myMainSel->ReactivateProjector();
      myMainSel->UpdateSort();
    }
    if(debugmode)
@@ -156,11 +155,10 @@ void AIS_InteractiveContext::CloseLocalContext(const Standard_Integer Index,
    if(GoodIndex==myCurLocalIndex){
      myCurLocalIndex = HighestIndex();
      const Handle(AIS_LocalContext)& LocCtx = myLocalContexts(myCurLocalIndex);
-     if(LocCtx->HasSameProjector(VS->Projector())){
-       LocCtx->MainSelector()->ReactivateProjector();
-     }
-     else
+     if (!LocCtx->HasSameProjector (VS->Projector()))
+     {
        LocCtx->MainSelector()->UpdateConversion();
+     }
    }
    else if(debugmode)
      cout<<"a No Current Local Context WasClosed"<<endl;
index 50ec0a8..a627f0e 100755 (executable)
@@ -16,8 +16,6 @@ Graphic3d_CLight.cxx
 Graphic3d_CLight.hxx
 Graphic3d_CPick.cxx
 Graphic3d_CPick.hxx
-Graphic3d_CPlane.cxx
-Graphic3d_CPlane.hxx
 Graphic3d_CBounds.cxx
 Graphic3d_CBounds.hxx
 Graphic3d_CUserDraw.cxx
@@ -54,4 +52,8 @@ Graphic3d_Vertex.hxx
 Graphic3d_Vertex.cxx
 Graphic3d_MarkerImage.hxx
 Graphic3d_MarkerImage.cxx
-Graphic3d_MarkerImage_Handle.hxx
\ No newline at end of file
+Graphic3d_MarkerImage_Handle.hxx
+Graphic3d_ClipPlane.hxx
+Graphic3d_ClipPlane.cxx
+Graphic3d_ClipPlane_Handle.hxx
+Graphic3d_SetOfHClipPlane.hxx
index bdf6960..aa39c28 100755 (executable)
@@ -399,6 +399,15 @@ is
     ---Purpose: Defines the C structure of a graduated trihedron.
     ---Category: Imported types
 
+    imported ClipPlane;
+    ---Purpose: Describes geometrical and auxiliary properties of clipping
+    -- planes applied on rendering by graphical driver.
+    ---Category: Imported types
+
+    imported ClipPlane_Handle;
+    ---Purpose: CDL-compatibility handle type definition for
+    -- clip plane objects.
+
     imported CTexture;
 
     imported CTransPersStruct;
@@ -575,6 +584,10 @@ is
     imported NListOfHAsciiString;
     ---Category: Instantiated classes
 
+    imported SetOfHClipPlane;
+    ---Category: Instantiated classes
+    -- Set of handles on clip planes
+
     deferred  class  TextureRoot  from  Graphic3d;
     deferred  class  TextureMap   from  Graphic3d;
     deferred  class  Texture1D    from  Graphic3d;
diff --git a/src/Graphic3d/Graphic3d_CPlane.hxx b/src/Graphic3d/Graphic3d_CPlane.hxx
deleted file mode 100755 (executable)
index 3ea9d49..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
-//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
-//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
-//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
-/*============================================================================*/
-/*==== Titre: Graphic3d_CPlane.hxx                                           */
-/*==== Role : The header file of primitive type "CPlane" from Graphic3d       */
-/*====                                                                       */
-/*==== Implementation:  This is a primitive type implemented with typedef     */
-/*============================================================================*/
-
-#ifndef _Graphic3d_CPlane_HeaderFile
-#define _Graphic3d_CPlane_HeaderFile
-
-#include <InterfaceGraphic_Graphic3d.hxx>
-#include <InterfaceGraphic_Visual3d.hxx>
-typedef CALL_DEF_PLANE Graphic3d_CPlane;
-
-#if defined(__cplusplus) || defined(c_plusplus)
-/*==== Definition de Type ====================================================*/
-#include <Standard_Type.hxx>
-const Handle(Standard_Type)& TYPE(Graphic3d_CPlane) ;
-/*============================================================================*/
-
-#endif
-#endif /*Graphic3d_CPlane_HeaderFile*/
index c00cc33..5f96ef8 100755 (executable)
@@ -20,6 +20,7 @@
 #define _Graphic3d_CStructure_HeaderFile
 
 #include <Graphic3d_CGroup.hxx>
+#include <Graphic3d_SetOfHClipPlane.hxx>
 
 class Graphic3d_CStructure
 {
@@ -55,6 +56,7 @@ public:
 
   CALL_DEF_TRANSFORM_PERSISTENCE TransformPersistence;
 
+  Graphic3d_SetOfHClipPlane ClipPlanes;
 };
 
 ///typedef Graphic3d_CStructure CALL_DEF_STRUCTURE;
index fc81011..93b524d 100755 (executable)
@@ -22,6 +22,7 @@
 #include <InterfaceGraphic_Visual3d.hxx>
 #include <Handle_Graphic3d_TextureEnv.hxx>
 #include <Standard_Type.hxx>
+#include <Graphic3d_SetOfHClipPlane.hxx>
 
 class CALL_DEF_VIEWCONTEXT
 {
@@ -42,9 +43,8 @@ public:
     Visualization (0),
     NbActiveLight (0),
     ActiveLight (NULL),
-    NbActivePlane (0),
-    ActivePlane (NULL),
-    SurfaceDetail (0)
+    SurfaceDetail (0),
+    ClipPlanes()
   {
     //
   }
@@ -71,12 +71,10 @@ public:
   int   NbActiveLight;
   CALL_DEF_LIGHT* ActiveLight;
 
-  int   NbActivePlane;
-  CALL_DEF_PLANE* ActivePlane;
-
   Handle(Graphic3d_TextureEnv) TextureEnv;
   int   SurfaceDetail;
 
+  Graphic3d_SetOfHClipPlane ClipPlanes;
 };
 
 class Graphic3d_CView
diff --git a/src/Graphic3d/Graphic3d_ClipPlane.cxx b/src/Graphic3d/Graphic3d_ClipPlane.cxx
new file mode 100644 (file)
index 0000000..f732444
--- /dev/null
@@ -0,0 +1,251 @@
+// Created on: 2013-07-12
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+
+#include <Graphic3d_ClipPlane.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
+#include <gp_Pln.hxx>
+#include <Standard_Atomic.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(Graphic3d_ClipPlane, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(Graphic3d_ClipPlane, Standard_Transient)
+
+namespace
+{
+  static volatile Standard_Integer THE_CLIP_PLANE_COUNTER = 0;
+};
+
+// =======================================================================
+// function : Graphic3d_ClipPlane
+// purpose  :
+// =======================================================================
+Graphic3d_ClipPlane::Graphic3d_ClipPlane()
+: myEquation (0.0, 0.0, 1.0, 0.0),
+  myIsOn (Standard_True),
+  myIsCapping (Standard_False),
+  myMaterial (Graphic3d_NOM_DEFAULT),
+  myTexture (NULL),
+  myHatch (Aspect_HS_HORIZONTAL),
+  myHatchOn (Standard_False),
+  myId(),
+  myEquationMod(0),
+  myAspectMod(0)
+{
+  MakeId();
+}
+
+// =======================================================================
+// function : Graphic3d_ClipPlane
+// purpose  :
+// =======================================================================
+Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Equation& theEquation)
+: myEquation (theEquation),
+  myIsOn (Standard_True),
+  myIsCapping (Standard_False),
+  myMaterial (Graphic3d_NOM_DEFAULT),
+  myTexture (NULL),
+  myHatch (Aspect_HS_HORIZONTAL),
+  myHatchOn (Standard_False),
+  myId(),
+  myEquationMod(0),
+  myAspectMod(0)
+{
+  MakeId();
+}
+
+// =======================================================================
+// function : Graphic3d_ClipPlane
+// purpose  :
+// =======================================================================
+Graphic3d_ClipPlane::Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther)
+: myEquation (theOther.myEquation),
+  myIsOn (theOther.myIsOn),
+  myIsCapping (theOther.myIsCapping),
+  myMaterial (theOther.myMaterial),
+  myTexture (theOther.myTexture),
+  myHatch (theOther.myHatch),
+  myHatchOn (theOther.myHatchOn),
+  myId(),
+  myEquationMod (0),
+  myAspectMod (0)
+{
+  MakeId();
+}
+
+// =======================================================================
+// function : Graphic3d_ClipPlane
+// purpose  :
+// =======================================================================
+Graphic3d_ClipPlane::Graphic3d_ClipPlane(const gp_Pln& thePlane)
+: myEquation (),
+  myIsOn (Standard_True),
+  myIsCapping (Standard_False),
+  myMaterial (Graphic3d_NOM_DEFAULT),
+  myTexture (NULL),
+  myHatch (Aspect_HS_HORIZONTAL),
+  myHatchOn (Standard_False),
+  myId(),
+  myEquationMod(0),
+  myAspectMod(0)
+{
+  MakeId();
+  SetEquation (thePlane);
+}
+
+// =======================================================================
+// function : SetEquation
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetEquation (const Equation& theEquation)
+{
+  myEquation = theEquation;
+  myEquationMod++;
+}
+
+// =======================================================================
+// function : SetPlane
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetEquation (const gp_Pln& thePlane)
+{
+  thePlane.Coefficients (myEquation[0],
+                         myEquation[1],
+                         myEquation[2],
+                         myEquation[3]);
+  myEquationMod++;
+}
+
+// =======================================================================
+// function : SetOn
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetOn (const Standard_Boolean theIsOn)
+{
+  myIsOn = theIsOn;
+}
+
+// =======================================================================
+// function : SetCapping
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCapping (const Standard_Boolean theIsOn)
+{
+  myIsCapping = theIsOn;
+}
+
+// =======================================================================
+// function : ToPlane
+// purpose  :
+// =======================================================================
+gp_Pln Graphic3d_ClipPlane::ToPlane() const
+{
+  return gp_Pln (myEquation[0],
+                 myEquation[1],
+                 myEquation[2],
+                 myEquation[3]);
+}
+
+// =======================================================================
+// function : Clone
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane::Clone() const
+{
+  return new Graphic3d_ClipPlane(*this);
+}
+
+// =======================================================================
+// function : SetCappingMaterial
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingMaterial (const Graphic3d_MaterialAspect& theMat)
+{
+  myMaterial = theMat;
+  myAspectMod++;
+}
+
+// =======================================================================
+// function : SetCappingTexture
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture)
+{
+  myTexture = theTexture;
+  myAspectMod++;
+}
+
+// =======================================================================
+// function : SetCappingHatch
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatch (const Aspect_HatchStyle theStyle)
+{
+  myHatch = theStyle;
+  myAspectMod++;
+}
+
+// =======================================================================
+// function : SetCappingHatchOn
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatchOn()
+{
+  myHatchOn = Standard_True;
+  myAspectMod++;
+}
+
+// =======================================================================
+// function : SetCappingHatchOff
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::SetCappingHatchOff()
+{
+  myHatchOn = Standard_False;
+  myAspectMod++;
+}
+
+// =======================================================================
+// function : MakeId
+// purpose  :
+// =======================================================================
+void Graphic3d_ClipPlane::MakeId()
+{
+  myId = TCollection_AsciiString ("Graphic3d_ClipPlane_") //DynamicType()->Name()
+       + TCollection_AsciiString (Standard_Atomic_Increment (&THE_CLIP_PLANE_COUNTER));
+}
+
+// =======================================================================
+// function : CappingAspect
+// purpose  :
+// =======================================================================
+Handle(Graphic3d_AspectFillArea3d) Graphic3d_ClipPlane::CappingAspect() const
+{
+  Handle(Graphic3d_AspectFillArea3d) anAspect = new Graphic3d_AspectFillArea3d();
+  anAspect->SetDistinguishOff();
+  anAspect->SetFrontMaterial (myMaterial);
+  anAspect->SetTextureMap (myTexture);
+  anAspect->SetHatchStyle (myHatch);
+  anAspect->SetInteriorStyle (myHatchOn ? Aspect_IS_HATCH : Aspect_IS_SOLID);
+  anAspect->SetInteriorColor (myMaterial.Color());
+  if (!myTexture.IsNull())
+    anAspect->SetTextureMapOn();
+  else
+    anAspect->SetTextureMapOff();
+
+  return anAspect;
+}
diff --git a/src/Graphic3d/Graphic3d_ClipPlane.hxx b/src/Graphic3d/Graphic3d_ClipPlane.hxx
new file mode 100644 (file)
index 0000000..16e48d0
--- /dev/null
@@ -0,0 +1,228 @@
+// Created on: 2013-07-12
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+
+#ifndef _Graphic3d_ClipPlane_HeaderFile
+#define _Graphic3d_ClipPlane_HeaderFile
+
+#include <Standard_Macro.hxx>
+#include <Standard_TypeDef.hxx>
+#include <Standard_Transient.hxx>
+#include <NCollection_Vec4.hxx>
+#include <Graphic3d_MaterialAspect.hxx>
+#include <Graphic3d_TextureMap.hxx>
+#include <Aspect_HatchStyle.hxx>
+
+DEFINE_STANDARD_HANDLE (Graphic3d_ClipPlane, Standard_Transient)
+
+class gp_Pln;
+class Graphic3d_AspectFillArea3d;
+class Handle(Graphic3d_AspectFillArea3d);
+
+//! Container for properties describing graphic driver clipping planes.
+//! It is up to application to create instances of this class and specify its
+//! properties. The instances are passed into graphic driver or other facilities
+//! that implement clipping features (e.g. selection).
+//! Depending on usage context the class can be used to specify:
+//! - Global clipping applied over the whole scene.
+//! - Object-level clipping applied for each particular object.
+//! Please note that the set of planes can define convex clipping volume.
+//! Be aware that number of clip planes supported by OpenGl is implementation
+//! dependant: at least 6 planes are available. Thus, take into account
+//! number of clipping planes passed for rendering: the object planes plus
+//! the view defined ones.
+class Graphic3d_ClipPlane : public Standard_Transient
+{
+public:
+
+  typedef NCollection_Vec4<Standard_Real> Equation;
+
+  //! Default constructor.
+  //! Initializes clip plane container with the following properties:
+  //! - Equation (0.0, 0.0, 1.0, 0)
+  //! - IsOn (True),
+  //! - IsCapping (False),
+  //! - Material (Graphic3d_NOM_DEFAULT),
+  //! - Texture (NULL),
+  //! - HatchStyle (Aspect_HS_HORIZONTAL),
+  //! - IsHatchOn (False)
+  Standard_EXPORT Graphic3d_ClipPlane();
+
+  //! Copy constructor.
+  //! @param theOther [in] the copied plane.
+  Standard_EXPORT Graphic3d_ClipPlane(const Graphic3d_ClipPlane& theOther);
+
+  //! Construct clip plane for the passed equation.
+  //! By default the plane is on, capping is turned off.
+  //! @param theEquation [in] the plane equation.
+  Standard_EXPORT Graphic3d_ClipPlane (const Equation& theEquation);
+
+  //! Construct clip plane from the passed geomertical definition.
+  //! By default the plane is on, capping is turned off.
+  //! @param thePlane [in] the plane.
+  Standard_EXPORT Graphic3d_ClipPlane (const gp_Pln& thePlane);
+
+  //! Set plane equation by its geometrical definition.
+  //! @param thePlane [in] the plane.
+  Standard_EXPORT void SetEquation (const gp_Pln& thePlane);
+
+  //! Set 4-component equation vector for clipping plane.
+  //! @param theEquation [in] the XYZW (or "ABCD") equation vector.
+  Standard_EXPORT void SetEquation (const Equation& theEquation);
+
+  //! Get 4-component equation vector for clipping plane.
+  //! @return clipping plane equation vector.
+  const Equation& GetEquation() const
+  {
+    return myEquation;
+  }
+
+  //! Check that the clipping plane is turned on.
+  //! @return boolean flag indicating whether the plane is in on or off state.
+  Standard_Boolean IsOn() const
+  {
+    return myIsOn;
+  }
+
+  //! Change state of the clipping plane.
+  //! @param theIsOn [in] the flag specifying whether the graphic driver
+  //! clipping by this plane should be turned on or off.
+  Standard_EXPORT void SetOn(const Standard_Boolean theIsOn);
+
+  //! Change state of capping surface rendering.
+  //! @param theIsOn [in] the flag specifying whether the graphic driver should
+  //! perform rendering of capping surface produced by this plane. The graphic
+  //! driver produces this surface for convex graphics by means of stencil-test
+  //! and multipass rendering.
+  Standard_EXPORT void SetCapping(const Standard_Boolean theIsOn);
+
+  //! Check state of capping surface rendering.
+  //! @return true (turned on) or false depending on the state.
+  Standard_Boolean IsCapping() const
+  {
+    return myIsCapping;
+  }
+
+  //! Get geomertical definition. The plane is built up
+  //! from the equation clipping plane equation vector.
+  //! @return geometrical definition of clipping plane.
+  Standard_EXPORT gp_Pln ToPlane() const;
+
+  //! Clone plane. Virtual method to simplify copying procedure if plane
+  //! class is redefined at application level to add specific fields to it
+  //! e.g. id, name, etc.
+  //! @return new instance of clipping plane with same properties and attributes.
+  Standard_EXPORT virtual Handle(Graphic3d_ClipPlane) Clone() const;
+
+public: // @name user-defined graphical attributes
+
+  //! Set material for rendering capping surface.
+  //! @param theMat [in] the material.
+  Standard_EXPORT void SetCappingMaterial (const Graphic3d_MaterialAspect& theMat);
+
+  //! @return capping material.
+  const Graphic3d_MaterialAspect& CappingMaterial() const
+  {
+    return myMaterial;
+  }
+
+  //! Set texture to be applied on capping surface.
+  //! @param theTexture [in] the texture.
+  Standard_EXPORT void SetCappingTexture (const Handle(Graphic3d_TextureMap)& theTexture);
+
+  //! @return capping texture map.
+  const Handle(Graphic3d_TextureMap)& CappingTexture() const
+  {
+    return myTexture;
+  }
+
+  //! Set hatch style (stipple) and turn hatching on.
+  //! @param theStyle [in] the hatch style.
+  Standard_EXPORT void SetCappingHatch (const Aspect_HatchStyle theStyle);
+
+  //! @return hatching style.
+  Aspect_HatchStyle CappingHatch() const
+  {
+    return myHatch;
+  }
+
+  //! Turn on hatching.
+  Standard_EXPORT void SetCappingHatchOn();
+
+  //! Turn off hatching.
+  Standard_EXPORT void SetCappingHatchOff();
+
+  //! @return True if hatching mask is turned on.
+  Standard_Boolean IsHatchOn() const
+  {
+    return myHatchOn;
+  }
+
+  //! This ID is used for managing associated resources in graphical driver.
+  //! The clip plane can be assigned within a range of IO which can be
+  //! displayed in separate OpenGl contexts. For each of the context an associated
+  //! OpenGl resource for graphical aspects should be created and kept.
+  //! The resources are stored in graphical driver for each of individual groups
+  //! of shared context under the clip plane identifier.
+  //! @return clip plane resource identifier string.
+  const TCollection_AsciiString& GetId() const
+  {
+    return myId;
+  }
+
+  //! Compute and return capping apsect from the graphical attributes.
+  //! @return capping surface rendering aspect.
+  Standard_EXPORT Handle(Graphic3d_AspectFillArea3d) CappingAspect() const;
+
+public: // @name modificaton counters
+
+  //! @return modification counter for equation.
+  unsigned int MCountEquation() const
+  {
+    return myEquationMod;
+  }
+
+  //! @return modification counter for aspect.
+  unsigned int MCountAspect() const
+  {
+    return myAspectMod;
+  }
+
+private:
+
+  void MakeId();
+
+private:
+
+  Equation                     myEquation;    //!< Plane equation vector.
+  Standard_Boolean             myIsOn;        //!< State of the clipping plane.
+  Standard_Boolean             myIsCapping;   //!< State of graphic driver capping.
+  Graphic3d_MaterialAspect     myMaterial;    //!< Capping surface material.
+  Handle(Graphic3d_TextureMap) myTexture;     //!< Capping surface texture.
+  Aspect_HatchStyle            myHatch;       //!< Capping surface hatch mask.
+  Standard_Boolean             myHatchOn;     //!< Capping surface hatching flag.
+  TCollection_AsciiString      myId;          //!< Resource id.
+  unsigned int                 myEquationMod; //!< Modification counter for equation.
+  unsigned int                 myAspectMod;   //!< Modification counter of aspect.
+
+public:
+
+  DEFINE_STANDARD_RTTI(Graphic3d_ClipPlane);
+};
+
+#endif
diff --git a/src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx b/src/Graphic3d/Graphic3d_ClipPlane_Handle.hxx
new file mode 100644 (file)
index 0000000..db5905a
--- /dev/null
@@ -0,0 +1,26 @@
+// Created on: 2013-07-12
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+
+#ifndef _Graphic3d_ClipPlane_Handle_HeaderFile
+#define _Graphic3d_ClipPlane_Handle_HeaderFile
+
+#include <Graphic3d_ClipPlane.hxx>
+typedef Handle(Graphic3d_ClipPlane) Graphic3d_ClipPlane_Handle;
+
+#endif
index 0bef557..bc3fbec 100755 (executable)
@@ -90,7 +90,8 @@ uses
     CUserDraw           from Graphic3d,
     NListOfHAsciiString from Graphic3d,
     FontAspect          from Font,
-    CGraduatedTrihedron from Graphic3d
+    CGraduatedTrihedron from Graphic3d,
+    ClipPlane           from Graphic3d
 
 raises
 
@@ -407,10 +408,11 @@ is
         is deferred;
     ---Purpose: call_togl_setlight
 
-    SetPlane ( me       : mutable;
-               ACView   : CView from Graphic3d )
-        is deferred;
-    ---Purpose: call_togl_setplane
+    SetClipPlanes (me : mutable; theCView : CView from Graphic3d) is deferred;
+    ---Purpose: Pass clip planes to the associated graphic driver view.
+
+    SetClipPlanes (me : mutable; theCStructure : CStructure from Graphic3d) is deferred;
+    ---Purpose: Pass clip planes to the associated graphic driver structure.
 
     SetVisualisation ( me       : mutable;
                        ACView   : CView from Graphic3d )
@@ -952,12 +954,6 @@ is
         returns Integer from Standard;
     ---Purpose: call_togl_light
 
-    Plane ( myclass;
-        ACPlane : CPlane from Graphic3d;
-        Update  : Boolean from Standard )
-        returns Integer from Standard;
-    ---Purpose: call_togl_plane
-
     -----------------------------
     -- Category: Internal methods
     -----------------------------
@@ -978,10 +974,6 @@ is
                  ACPick    : CPick from Graphic3d;
                  AField    : Integer from Standard );
 
-    PrintCPlane ( me;
-                  ACPlane   : CPlane from Graphic3d;
-                  AField    : Integer from Standard );
-
     PrintCStructure ( me;
                       ACStructure   : CStructure from Graphic3d;
                       AField    : Integer from Standard );
index 0dea4c0..942dde5 100755 (executable)
@@ -66,16 +66,6 @@ Standard_Integer Graphic3d_GraphicDriver::Light (const Graphic3d_CLight& ACLight
 
 }
 
-Standard_Integer Graphic3d_GraphicDriver::Plane (const Graphic3d_CPlane& ACPlane, const Standard_Boolean Update) {
-
-  static Standard_Integer NbPlanes = 1;
-  Standard_Boolean Result;
-
-  Result = Update ? ACPlane.PlaneId : NbPlanes++;
-  return Result;
-
-}
-
 //-Internal methods, in order
 
 void Graphic3d_GraphicDriver::PrintBoolean (const Standard_CString AComment, const Standard_Boolean AValue) const {
@@ -135,16 +125,6 @@ void Graphic3d_GraphicDriver::PrintCPick (const Graphic3d_CPick& ACPick, const S
 
 }
 
-void Graphic3d_GraphicDriver::PrintCPlane (const Graphic3d_CPlane& ACPlane, const Standard_Integer AField) const {
-
-  if (AField) {
-    cout << "\tws id " << ACPlane.WsId << ", "
-      << "view id " << ACPlane.ViewId << "\n";
-    cout << flush;
-  }
-
-}
-
 void Graphic3d_GraphicDriver::PrintCStructure (const Graphic3d_CStructure& ACStructure, const Standard_Integer AField) const {
 
   if (AField) {
index 0107265..4d9a089 100644 (file)
@@ -186,7 +186,7 @@ const Handle(Image_PixMap)& Graphic3d_MarkerImage::GetImageAlpha()
         Standard_Byte* anImageRow = myImageAlpha->ChangeRow (aRowIter);
         for (Standard_Size aColumnIter = 0; aColumnIter < myImage->Width(); aColumnIter++)
         {
-          myImage->PixelColor (aColumnIter, aRowIter, anAlpha);
+          myImage->PixelColor ((Standard_Integer )aColumnIter, (Standard_Integer )aRowIter, anAlpha);
           anImageRow[aColumnIter] = Standard_Byte (255.0 * anAlpha);
         }
       }
diff --git a/src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx b/src/Graphic3d/Graphic3d_SetOfHClipPlane.hxx
new file mode 100644 (file)
index 0000000..a16dd1c
--- /dev/null
@@ -0,0 +1,30 @@
+// Created on: 2013-07-15
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+
+#ifndef _Graphic3d_SetOfHClipPlane_HeaderFile
+#define _Graphic3d_SetOfHClipPlane_HeaderFile
+
+#include <NCollection_Set.hxx>
+#include <Graphic3d_ClipPlane.hxx>
+
+// CDL-header shortcut for set of graphical clipping planes. This is a compact
+// way (compared to list) to store clippings, with mandatory uniqueness check.
+typedef NCollection_Set<Handle(Graphic3d_ClipPlane)> Graphic3d_SetOfHClipPlane;
+
+#endif
index e062d4a..a8bac35 100755 (executable)
@@ -74,7 +74,8 @@ uses
        Vector                  from Graphic3d,
        Vertex                  from Graphic3d,
        TransModeFlags          from Graphic3d,
-       Pnt                     from gp
+       Pnt                     from gp,
+    SetOfHClipPlane from Graphic3d
 
 raises
 
@@ -270,6 +271,15 @@ is
         ---Purpose: Get Z layer ID of displayed structure. The method
         -- returns -1 if the structure has no ID (deleted from graphic driver).
 
+    SetClipPlanes (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is static;
+    ---Purpose: Changes a set of clip planes slicing the structure on rendering.
+    -- @param thePlanes [in] the set of clip planes.
+
+    GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d;
+    ---C++: return const&
+    ---Purpose: Get clip planes slicing the structure on rendering.
+    -- @return set of clip planes.
+
        SetPick ( me            : mutable;
                  AValue        : Boolean from Standard )
                is static;
index 87ba9e8..702c686 100755 (executable)
@@ -2460,7 +2460,6 @@ Standard_Boolean Graphic3d_Structure::HLRValidation () const {
 //function : CStructure
 //purpose  :
 //=======================================================================
-
 Graphic3d_CStructure* Graphic3d_Structure::CStructure()
 {
   return &MyCStructure;
@@ -2470,7 +2469,6 @@ Graphic3d_CStructure* Graphic3d_Structure::CStructure()
 //function : SetZLayer
 //purpose  :
 //=======================================================================
-
 void Graphic3d_Structure::SetZLayer (const Standard_Integer theLayerId)
 {
   // if the structure is not displayed, unable to change its display layer
@@ -2484,8 +2482,26 @@ void Graphic3d_Structure::SetZLayer (const Standard_Integer theLayerId)
 //function : GetZLayer
 //purpose  :
 //=======================================================================
-
 Standard_Integer Graphic3d_Structure::GetZLayer () const
 {
   return MyStructureManager->GetZLayer (this);
 }
+
+//=======================================================================
+//function : SetClipPlanes
+//purpose  :
+//=======================================================================
+void Graphic3d_Structure::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes)
+{
+  MyCStructure.ClipPlanes = thePlanes;
+  MyGraphicDriver->SetClipPlanes (MyCStructure);
+}
+
+//=======================================================================
+//function : GetClipPlanes
+//purpose  :
+//=======================================================================
+const Graphic3d_SetOfHClipPlane& Graphic3d_Structure::GetClipPlanes() const
+{
+  return MyCStructure.ClipPlanes;
+}
index 9eeb99b..3218bb3 100755 (executable)
@@ -35,27 +35,6 @@ typedef struct {
 
 } CALL_DEF_VERTEX;
 
-
-/* MODELE CLIPPING */
-
-typedef struct {
-
-       int WsId;
-
-       int ViewId;
-
-       int PlaneId;
-
-       int Active;
-
-       float CoefA;
-       float CoefB;
-       float CoefC;
-       float CoefD;
-
-} CALL_DEF_PLANE;
-
-
 /* SOURCE LUMINEUSE */
 
 typedef struct {
index d94a9be..9ac80a4 100755 (executable)
@@ -27,7 +27,7 @@ class DummySensitiveEntity from MeshVS inherits SensitiveEntity from SelectBasic
 uses
   EntityOwner   from SelectBasics,
   ListOfBox2d   from SelectBasics,
-
+  PickArgs      from SelectBasics,
   Array1OfPnt2d from TColgp,
 
   Box2d         from Bnd
@@ -38,9 +38,10 @@ is
    Areas    ( me: mutable;
               aresult: in out ListOfBox2d from SelectBasics ) is redefined;
 
-   Matches  ( me: mutable;
-              X, Y, aTol: Real;
-              DMin: out Real ) returns Boolean is redefined;
+   Matches (me : mutable;
+            thePickArgs : PickArgs from SelectBasics;
+            theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined;
 
    Matches  ( me: mutable;
               XMin, YMin, XMax, YMax, aTol: Real ) returns Boolean is redefined;
index 967c2e5..b002101 100755 (executable)
@@ -42,9 +42,8 @@ void MeshVS_DummySensitiveEntity::Areas( SelectBasics_ListOfBox2d& )
 // Function : Matches
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const Standard_Real,
-                                                       const Standard_Real,
-                                                       const Standard_Real,
+Standard_Boolean MeshVS_DummySensitiveEntity::Matches( const SelectBasics_PickArgs&,
+                                                       Standard_Real&,
                                                        Standard_Real& )
 {
   return Standard_False;
index 2065ad2..873bfb1 100755 (executable)
@@ -30,7 +30,8 @@ uses
   Box2d from Bnd, 
   Location from TopLoc, 
   Lin from gp, 
-  ListOfBox2d from SelectBasics, 
+  ListOfBox2d from SelectBasics,
+  PickArgs from SelectBasics,
   Projector from Select3D      
 is
 
@@ -42,15 +43,12 @@ is
      
   GetConnected( me: mutable;  aLocation  :  Location from TopLoc )
     returns SensitiveEntity from Select3D is redefined; 
-     
-  ComputeDepth( me;  EyeLine  :  Lin from gp ) returns Real from Standard 
-    is redefined;     
-           
-  Matches( me: mutable;  X,Y : Real from Standard;
-                        aTol: Real from Standard;
-                        DMin: out Real from Standard ) returns Boolean  
-    is redefined;
+
+  Matches (me : mutable;
+           thePickArgs : PickArgs from SelectBasics;
+           theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined;
+
   Matches  ( me: mutable;   XMin, YMin, XMax, YMax  : Real;
                            aTol                    : Real ) returns Boolean  
     is redefined;
index 0a094a6..a9f715a 100755 (executable)
@@ -60,13 +60,13 @@ Standard_Integer MeshVS_SensitiveMesh::GetMode () const
 // name    : Matches
 // Purpose :
 //=======================================================================
-Standard_Boolean MeshVS_SensitiveMesh::Matches(const Standard_Real X,
-                                              const Standard_Real Y,
-                                              const Standard_Real aTol,
-                                              Standard_Real&  DMin)
+Standard_Boolean MeshVS_SensitiveMesh::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                Standard_Real& theMatchDMin,
+                                                Standard_Real& theMatchDepth)
 {
-  DMin = 0.;
-  
+  theMatchDMin = 0.0;
+  theMatchDepth = Precision::Infinite();
+
   Handle(MeshVS_MeshOwner) anOwner = Handle(MeshVS_MeshOwner)::DownCast( OwnerId() );
   if( anOwner.IsNull() ) return Standard_False;
   Handle(MeshVS_Mesh) aMeshPrs = Handle(MeshVS_Mesh)::DownCast( anOwner->Selectable() );
@@ -75,12 +75,17 @@ Standard_Boolean MeshVS_SensitiveMesh::Matches(const Standard_Real X,
   if( aDS.IsNull() ) return Standard_False;
   Handle(TColStd_HPackedMapOfInteger) NodesMap;
   Handle(TColStd_HPackedMapOfInteger) ElemsMap;
+
   // Mesh data source should provide the algorithm for computation
   // of detected entities from 2D point
-  Standard_Boolean isDetected = aDS->GetDetectedEntities( aMeshPrs, X, Y, aTol, NodesMap, ElemsMap, DMin );
+  Standard_Boolean isDetected =
+    aDS->GetDetectedEntities (aMeshPrs, thePickArgs.X(), thePickArgs.Y(),
+                              thePickArgs.Tolerance(), NodesMap,
+                              ElemsMap, theMatchDMin);
+
   // The detected entites will be available from mesh owner
   anOwner->SetDetectedEntities( NodesMap, ElemsMap );
-  
+
   return isDetected;
 }
 
@@ -148,15 +153,6 @@ Handle(Select3D_SensitiveEntity) MeshVS_SensitiveMesh::GetConnected( const TopLo
   return aMeshEnt;
 }
 
-//=======================================================================
-//function : ComputeDepth
-//purpose  : 
-//=======================================================================
-Standard_Real MeshVS_SensitiveMesh::ComputeDepth( const gp_Lin& /*EyeLine*/ ) const
-{
-  return Precision::Infinite();
-}
-
 //==================================================
 // Function: ProjectOneCorner
 // Purpose :
@@ -181,8 +177,6 @@ void MeshVS_SensitiveMesh::ProjectOneCorner(const Handle(Select3D_Projector)& th
 //==================================================
 void MeshVS_SensitiveMesh::Project(const Handle(Select3D_Projector)& aProj)
 {
-  Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
-
   mybox2d.SetVoid();
   if (mybox.IsVoid())
     return;
index e9091ec..906ce67 100755 (executable)
@@ -31,6 +31,7 @@ uses
     Box2d                      from Bnd,
     Lin                        from gp,
     ListOfBox2d                from SelectBasics,
+    PickArgs                   from SelectBasics,
     Array1OfPnt                from TColgp,
     HArray1OfPnt               from TColgp,
     HArray1OfPnt2d             from TColgp,
@@ -47,10 +48,10 @@ is
     GetConnected( me:mutable; aLocation: Location from TopLoc ) returns SensitiveEntity from Select3D 
        is redefined;
    
-    Matches( me   : mutable; 
-             X,Y  : Real from Standard;
-             aTol : Real from Standard;
-             DMin : out Real from Standard ) returns Boolean is redefined;
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+      returns Boolean is redefined;
 
     Matches( me                  : mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -66,7 +67,7 @@ is
     FindIntersection( me; NodesIndices : SequenceOfInteger from TColStd;
                           EyeLine      : Lin from gp ) returns Real is protected;
 
-    ComputeDepth( me; EyeLine: Lin from gp ) returns Real from Standard is redefined;
+    ComputeDepth( me; EyeLine: Lin from gp ) returns Real from Standard is virtual;
 
 --  ComputeSize( me ) returns Real from Standard is redefined;
 
index 847d0b6..bf767c6 100755 (executable)
@@ -33,7 +33,7 @@ MeshVS_SensitivePolyhedron::
 MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner,
                             const TColgp_Array1OfPnt& Nodes,
                             const Handle( MeshVS_HArray1OfSequenceOfInteger )& Topo )
-: Select3D_SensitiveEntity( Owner ),  
+: Select3D_SensitiveEntity( Owner ),
   myTopo( Topo )
 {
   Standard_Integer low = Nodes.Lower(), up = Nodes.Upper(), i;
@@ -51,8 +51,6 @@ MeshVS_SensitivePolyhedron( const Handle( SelectBasics_EntityOwner )& Owner,
 //================================================================
 void MeshVS_SensitivePolyhedron::Project( const Handle(Select3D_Projector)& aProjector )
 {
-  Select3D_SensitiveEntity::Project( aProjector );
-
   if( myNodes.IsNull() || myNodes2d.IsNull() )
     return;
 
@@ -115,10 +113,9 @@ void sort( Standard_Real& a, Standard_Real& b )
 // Function : Matches
 // Purpose  :
 //================================================================
-Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X,
-                                                      const Standard_Real Y,
-                                                      const Standard_Real aTol,
-                                                      Standard_Real& DMin )
+Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const SelectBasics_PickArgs& thePickArgs,
+                                                      Standard_Real& /*theMatchDMin*/,
+                                                      Standard_Real& theMatchDepth )
 {
   if( myNodes2d.IsNull() || myTopo.IsNull() )
     return Standard_False;
@@ -127,7 +124,7 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X,
                    R2  = myTopo->Upper(),
                    low = myNodes2d->Lower();
 
-  Standard_Real rTol = aTol*SensitivityFactor();
+  Standard_Real rTol = thePickArgs.Tolerance() * SensitivityFactor();
 
   Standard_Boolean inside = Standard_False;
 
@@ -149,15 +146,15 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X,
       y2 = myNodes2d->Value( low+next ).Y();
 
       if( Abs( x2-x1 )<Precision::Confusion() )
-      {  
+      {
         //vertical edge!!!
 
         sort( y1, y2 );
-        if( Y>=y1-rTol && Y<=y2+rTol && x1>X-rTol )
+        if ( thePickArgs.Y() >= y1 - rTol && thePickArgs.Y() <= y2 + rTol && x1 > thePickArgs.X() - rTol )
           intersect++;
       }
       else
-      {  
+      {
         //inclined edge!!!
 
         k = ( y2-y1 ) / ( x2-x1 );
@@ -165,9 +162,9 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X,
 
         if( Abs( k )>Precision::Confusion() )
         {
-          xp = ( Y-b ) / k; // absciss of point of intersection
+          xp = ( thePickArgs.Y() - b ) / k; // absciss of point of intersection
           sort( x1, x2 );
-          if( xp>=x1 && xp<=x2 && xp>X-rTol )
+          if( xp >= x1 && xp <= x2 && xp > thePickArgs.X() - rTol )
             intersect++;
         }
       }
@@ -177,8 +174,11 @@ Standard_Boolean MeshVS_SensitivePolyhedron::Matches( const Standard_Real X,
 
   if( inside )
   {
-    return Select3D_SensitiveEntity::Matches( X, Y, aTol, DMin );
+    theMatchDepth = ComputeDepth (thePickArgs.PickLine());
+
+    return !thePickArgs.IsClipped(theMatchDepth);
   }
+
   return Standard_False;
 }
 
@@ -226,7 +226,7 @@ Standard_Real MeshVS_SensitivePolyhedron::FindIntersection
 {
   Standard_Real val( Precision::Infinite() );
   for( Standard_Integer i=1, n=NodesIndices.Length(); i<=n; i++ )
-    val = Min( val, ElCLib::Parameter( 
+    val = Min( val, ElCLib::Parameter(
       EyeLine, myNodes->Value( myNodes->Lower()+NodesIndices.Value( i ) ) ) );
 
   return val;
@@ -265,7 +265,7 @@ Standard_Real MeshVS_SensitivePolyhedron::ComputeDepth( const gp_Lin& EyeLine )
 // Function : Areas
 // Purpose  :
 //================================================================
-void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult ) 
+void MeshVS_SensitivePolyhedron::Areas( SelectBasics_ListOfBox2d& aResult )
 {
   Bnd_Box2d aBox;
   GetBox2d( aBox );
index 9e596ae..65ba3e5 100755 (executable)
@@ -114,3 +114,11 @@ OpenGl_Vec.hxx
 OpenGl_VertexBuffer.hxx
 OpenGl_VertexBuffer.cxx
 OpenGl_VertexBufferEditor.hxx
+OpenGl_RenderFilter.hxx
+OpenGl_RenderFilter.cxx
+OpenGl_CappingAlgo.hxx
+OpenGl_CappingAlgo.cxx
+OpenGl_CappingPlaneResource.hxx
+OpenGl_CappingPlaneResource.cxx
+OpenGl_ClippingState.hxx
+OpenGl_ClippingState.cxx
index b5c5b16..428620d 100644 (file)
 #include <Aspect_PolygonOffsetMode.hxx>
 #include <Graphic3d_CGroup.hxx>
 #include <Graphic3d_TextureMap.hxx>
+#include <Graphic3d_TypeOfReflection.hxx>
+#include <Graphic3d_MaterialAspect.hxx>
+
+#include <NCollection_Vec3.hxx>
 
 namespace
 {
@@ -257,6 +261,145 @@ void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)&   theContext,
 }
 
 // =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_AspectFace::Init (const Handle(OpenGl_Context)&   theContext,
+                              const Handle(Graphic3d_AspectFillArea3d)& theAspect)
+{
+  CALL_DEF_CONTEXTFILLAREA aCAspect;
+  Standard_Real           aWidth;
+  Quantity_Color          aBackIntColor;
+  Quantity_Color          aEdgeColor;
+  Aspect_TypeOfLine       aLType;
+  Quantity_Color          aIntColor;
+  Aspect_InteriorStyle    aIntStyle;
+  NCollection_Vec3<Standard_Real> aColor;
+
+  theAspect->Values (aIntStyle, aIntColor, aBackIntColor, aEdgeColor, aLType, aWidth);
+  aIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
+
+  aCAspect.Style      = int (aIntStyle);
+  aCAspect.IntColor.r = float (aColor.r());
+  aCAspect.IntColor.g = float (aColor.g());
+  aCAspect.IntColor.b = float (aColor.b());
+
+  if (theAspect->Distinguish())
+  {
+    aBackIntColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
+  }
+
+  aCAspect.BackIntColor.r = float (aColor.r());
+  aCAspect.BackIntColor.g = float (aColor.g());
+  aCAspect.BackIntColor.b = float (aColor.b());
+
+  aCAspect.Edge = theAspect->Edge () ? 1:0;
+  aEdgeColor.Values (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
+
+  aCAspect.EdgeColor.r = float (aColor.r());
+  aCAspect.EdgeColor.g = float (aColor.g());
+  aCAspect.EdgeColor.b = float (aColor.b());
+  aCAspect.LineType    = int (aLType);
+  aCAspect.Width       = float (aWidth);
+  aCAspect.Hatch       = int (theAspect->HatchStyle ());
+
+  aCAspect.Distinguish = theAspect->Distinguish () ? 1:0;
+  aCAspect.BackFace    = theAspect->BackFace ()    ? 1:0;
+
+  aCAspect.Back.Shininess = float ((theAspect->BackMaterial ()).Shininess ());
+  aCAspect.Back.Ambient   = float ((theAspect->BackMaterial ()).Ambient ());
+  aCAspect.Back.Diffuse   = float ((theAspect->BackMaterial ()).Diffuse ());
+  aCAspect.Back.Specular  = float ((theAspect->BackMaterial ()).Specular ());
+  aCAspect.Back.Transparency  = float ((theAspect->BackMaterial ()).Transparency ());
+  aCAspect.Back.Emission      = float ((theAspect->BackMaterial ()).Emissive ());
+
+  // Reflection mode
+  aCAspect.Back.IsAmbient = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0 );
+  aCAspect.Back.IsDiffuse = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0 );
+  aCAspect.Back.IsSpecular = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0 );
+  aCAspect.Back.IsEmission = ((theAspect->BackMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0 );
+
+  // Material type
+  const Graphic3d_MaterialAspect aBackMat = theAspect->BackMaterial ();
+  Standard_Boolean isBackPhys = aBackMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
+  aCAspect.Back.IsPhysic = (isBackPhys ? 1 : 0 );
+
+  // Specular Color
+  aCAspect.Back.ColorSpec.r = float (((theAspect->BackMaterial ()).SpecularColor ()).Red ());
+  aCAspect.Back.ColorSpec.g = float (((theAspect->BackMaterial ()).SpecularColor ()).Green ());
+  aCAspect.Back.ColorSpec.b = float (((theAspect->BackMaterial ()).SpecularColor ()).Blue ());
+
+  // Ambient color
+  aCAspect.Back.ColorAmb.r = float (((theAspect->BackMaterial ()).AmbientColor ()).Red ());
+  aCAspect.Back.ColorAmb.g = float (((theAspect->BackMaterial ()).AmbientColor ()).Green ());
+  aCAspect.Back.ColorAmb.b = float (((theAspect->BackMaterial ()).AmbientColor ()).Blue ());
+
+  // Diffuse color
+  aCAspect.Back.ColorDif.r = float (((theAspect->BackMaterial ()).DiffuseColor ()).Red ());
+  aCAspect.Back.ColorDif.g = float (((theAspect->BackMaterial ()).DiffuseColor ()).Green ());
+  aCAspect.Back.ColorDif.b = float (((theAspect->BackMaterial ()).DiffuseColor ()).Blue ());
+
+  // Emissive color
+  aCAspect.Back.ColorEms.r = float (((theAspect->BackMaterial ()).EmissiveColor ()).Red ());
+  aCAspect.Back.ColorEms.g = float (((theAspect->BackMaterial ()).EmissiveColor ()).Green ());
+  aCAspect.Back.ColorEms.b = float (((theAspect->BackMaterial ()).EmissiveColor ()).Blue ());
+
+  aCAspect.Back.EnvReflexion = float ((theAspect->BackMaterial ()).EnvReflexion());
+
+  aCAspect.Front.Shininess    = float ((theAspect->FrontMaterial ()).Shininess ());
+  aCAspect.Front.Ambient      = float ((theAspect->FrontMaterial ()).Ambient ());
+  aCAspect.Front.Diffuse      = float ((theAspect->FrontMaterial ()).Diffuse ());
+  aCAspect.Front.Specular     = float ((theAspect->FrontMaterial ()).Specular ());
+  aCAspect.Front.Transparency = float ((theAspect->FrontMaterial ()).Transparency ());
+  aCAspect.Front.Emission     = float ((theAspect->FrontMaterial ()).Emissive ());
+
+  // Reflection mode
+  aCAspect.Front.IsAmbient    = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_AMBIENT) ? 1 : 0);
+  aCAspect.Front.IsDiffuse    = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_DIFFUSE) ? 1 : 0);
+  aCAspect.Front.IsSpecular   = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_SPECULAR) ? 1 : 0);
+  aCAspect.Front.IsEmission   = ((theAspect->FrontMaterial ()).ReflectionMode (Graphic3d_TOR_EMISSION) ? 1 : 0);
+
+  // Materail type
+  const Graphic3d_MaterialAspect aFrontMat = theAspect->FrontMaterial ();
+  Standard_Boolean isFrontPhys = aFrontMat.MaterialType (Graphic3d_MATERIAL_PHYSIC);
+  aCAspect.Front.IsPhysic = (isFrontPhys ? 1 : 0 );
+
+  // Specular Color
+  aCAspect.Front.ColorSpec.r = float (((theAspect->FrontMaterial ()).SpecularColor ()).Red ());
+  aCAspect.Front.ColorSpec.g = float (((theAspect->FrontMaterial ()).SpecularColor ()).Green ());
+  aCAspect.Front.ColorSpec.b = float (((theAspect->FrontMaterial ()).SpecularColor ()).Blue ());
+
+  // Ambient color
+  aCAspect.Front.ColorAmb.r = float (((theAspect->FrontMaterial ()).AmbientColor ()).Red ());
+  aCAspect.Front.ColorAmb.g = float (((theAspect->FrontMaterial ()).AmbientColor ()).Green ());
+  aCAspect.Front.ColorAmb.b = float (((theAspect->FrontMaterial ()).AmbientColor ()).Blue ());
+
+  // Diffuse color
+  aCAspect.Front.ColorDif.r = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Red ());
+  aCAspect.Front.ColorDif.g = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Green ());
+  aCAspect.Front.ColorDif.b = float (((theAspect->FrontMaterial ()).DiffuseColor ()).Blue ());
+
+  // Emissive color
+  aCAspect.Front.ColorEms.r = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Red ());
+  aCAspect.Front.ColorEms.g = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Green ());
+  aCAspect.Front.ColorEms.b = float (((theAspect->FrontMaterial ()).EmissiveColor ()).Blue ());
+
+  aCAspect.Front.EnvReflexion = float ((theAspect->FrontMaterial ()).EnvReflexion());
+  aCAspect.IsDef = 1;
+  aCAspect.Texture.TextureMap   = theAspect->TextureMap();
+  aCAspect.Texture.doTextureMap = theAspect->TextureMapState() ? 1 : 0;
+
+  Standard_Integer aPolyMode;
+  Standard_ShortReal aPolyFactor, aPolyUnits;
+  theAspect->PolygonOffsets (aPolyMode, aPolyFactor, aPolyUnits);
+  aCAspect.PolygonOffsetMode   = aPolyMode;
+  aCAspect.PolygonOffsetFactor = (Standard_ShortReal)aPolyFactor;
+  aCAspect.PolygonOffsetUnits  = (Standard_ShortReal)aPolyUnits;
+
+  Init (theContext, aCAspect);
+}
+
+// =======================================================================
 // function : Render
 // purpose  :
 // =======================================================================
index 7dbb2bf..198c08e 100644 (file)
 #include <Aspect_InteriorStyle.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Handle_Graphic3d_TextureParams.hxx>
-
 #include <OpenGl_AspectLine.hxx>
 #include <OpenGl_Element.hxx>
 #include <Handle_OpenGl_Texture.hxx>
+#include <Graphic3d_AspectFillArea3d.hxx>
 
 #define OPENGL_AMBIENT_MASK  (1<<0)
 #define OPENGL_DIFFUSE_MASK  (1<<1)
@@ -57,6 +57,9 @@ public:
   void Init (const Handle(OpenGl_Context)&   theContext,
              const CALL_DEF_CONTEXTFILLAREA& theAspect);
 
+  void Init (const Handle(OpenGl_Context)&             theContext,
+             const Handle(Graphic3d_AspectFillArea3d)& theAspect);
+
   void SetAspectEdge (const OpenGl_AspectLine* theAspectEdge) { myAspectEdge = *theAspectEdge; }
 
   const OpenGl_AspectLine* AspectEdge() const { return &myAspectEdge; }
diff --git a/src/OpenGl/OpenGl_CappingAlgo.cxx b/src/OpenGl/OpenGl_CappingAlgo.cxx
new file mode 100644 (file)
index 0000000..3340a97
--- /dev/null
@@ -0,0 +1,284 @@
+// Created on: 2013-09-05
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OpenGl_CappingAlgo.hxx>
+#include <OpenGl_Workspace.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_PrimitiveArray.hxx>
+#include <OpenGl_CappingPlaneResource.hxx>
+#include <OpenGl_Vec.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
+
+Handle(OpenGl_RenderFilter) OpenGl_CappingAlgo::myRenderFilter;
+OpenGl_AspectFace OpenGl_CappingAlgo::myFrontCulling;
+OpenGl_AspectFace OpenGl_CappingAlgo::myNoneCulling;
+Standard_Boolean OpenGl_CappingAlgo::myIsInit = Standard_False;
+
+namespace
+{
+  static const OpenGl_Vec4 THE_CAPPING_PLN_VERTS[12] =
+    { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 1.0f, 0.0f),
+      OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f,-1.0f, 0.0f),
+      OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
+
+  static const OpenGl_Vec4 THE_CAPPING_PLN_TCOORD[12] = 
+    { OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 0.0f, 1.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 (-1.0f, 0.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 0.0f, 0.0f, 0.0f, 1.0f),
+      OpenGl_Vec4 ( 0.0f,-1.0f, 0.0f, 0.0f),
+      OpenGl_Vec4 ( 1.0f, 0.0f, 0.0f, 0.0f) };
+};
+
+// =======================================================================
+// function : RenderCapping
+// purpose  :
+// =======================================================================
+void OpenGl_CappingAlgo::RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
+                                        const OpenGl_ListOfGroup& theGroups)
+{
+  // do not draw capping surface for second transparency pass
+  if (theWorkspace->NamedStatus & OPENGL_NS_2NDPASSDO)
+    return;
+
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+
+  // check whether algorithm need to be runned
+  Standard_Boolean isCapping = Standard_False;
+  Graphic3d_SetOfHClipPlane aContextPlanes = aContext->Clipping().Planes();
+  Graphic3d_SetOfHClipPlane::Iterator aCappingIt (aContextPlanes);
+  for (; aCappingIt.More(); aCappingIt.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aPlane = aCappingIt.Value();
+    if (aPlane->IsCapping())
+    {
+      isCapping = Standard_True;
+      break;
+    }
+  }
+
+  // do not perform algorithm is there is nothing to render
+  if (!isCapping)
+    return;
+
+  // init internal data
+  Init();
+
+  // remember current aspect face defined in workspace
+  const OpenGl_AspectFace* aFaceAsp = theWorkspace->AspectFace (Standard_False);
+
+  // replace primitive groups rendering filter
+  static Handle(OpenGl_CappingAlgoFilter) aCappingFilter = new OpenGl_CappingAlgoFilter();
+  Handle(OpenGl_RenderFilter) aRenderFilter = theWorkspace->GetRenderFilter();
+  theWorkspace->SetRenderFilter (aCappingFilter);
+
+  // prepare for rendering the clip planes
+  glEnable (GL_STENCIL_TEST);
+
+  // generate capping for every clip plane
+  for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
+  {
+    // get plane being rendered
+    const Handle(Graphic3d_ClipPlane)& aRenderPlane = aCappingIt.Value();
+    if (!aRenderPlane->IsCapping())
+    {
+      continue;
+    }
+
+    // enable only the rendering plane to generate stencil mask
+    Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (aContextPlanes);
+    for (; aPlaneIt.More(); aPlaneIt.Next())
+    {
+      const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+      const Standard_Boolean isOn = (aPlane == aRenderPlane);
+      aContext->ChangeClipping().SetEnabled (aPlane, isOn);
+    }
+
+    glClear (GL_STENCIL_BUFFER_BIT);
+    glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+    // override aspects, disable culling
+    theWorkspace->SetAspectFace (NoneCulling());
+    theWorkspace->AspectFace (Standard_True);
+
+    // evaluate number of pair faces
+    glDisable (GL_DEPTH_TEST);
+    glDepthMask (GL_FALSE);
+    glStencilFunc (GL_ALWAYS, 1, 0x01);
+    glStencilOp (GL_KEEP, GL_INVERT, GL_INVERT);
+
+    OpenGl_ListOfGroup::Iterator aGroupIt (theGroups);
+    for (; aGroupIt.More(); aGroupIt.Next())
+    {
+      aGroupIt.Value()->Render (theWorkspace);
+    }
+
+    // override material, cull backfaces
+    theWorkspace->SetAspectFace (FrontCulling());
+    theWorkspace->AspectFace (Standard_True);
+
+    // enable all clip plane except the rendered one
+    for (aPlaneIt.Init (aContextPlanes); aPlaneIt.More(); aPlaneIt.Next())
+    {
+      const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+      const Standard_Boolean isOn = (aPlane != aRenderPlane);
+      aContext->ChangeClipping().SetEnabled (aPlane, isOn);
+    }
+
+    // render capping plane using the generated stencil mask
+    glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+    glDepthMask (GL_TRUE);
+    glDepthFunc (GL_LESS);
+    glStencilFunc (GL_EQUAL, 1, 0x01);
+    glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
+    glEnable (GL_DEPTH_TEST);
+
+    RenderPlane (theWorkspace, aRenderPlane);
+  }
+
+  // restore previous application state
+  glClear (GL_STENCIL_BUFFER_BIT);
+  glStencilFunc (GL_ALWAYS, 0, 0xFF);
+  glDisable (GL_STENCIL_TEST);
+
+  // enable clipping
+  for (aCappingIt.Init (aContextPlanes); aCappingIt.More(); aCappingIt.Next())
+  {
+    aContext->ChangeClipping().SetEnabled (aCappingIt.Value(), Standard_True);
+  }
+
+  // restore rendering aspects
+  theWorkspace->SetAspectFace (aFaceAsp);
+  theWorkspace->SetRenderFilter (aRenderFilter);
+}
+
+// =======================================================================
+// function : RenderPlane
+// purpose  :
+// =======================================================================
+void OpenGl_CappingAlgo::RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
+                                      const Handle(Graphic3d_ClipPlane)& thePlane)
+{
+  const Handle(OpenGl_Context)& aContext = theWorkspace->GetGlContext();
+
+  // get resource for the plane
+  TCollection_AsciiString aResId = thePlane->GetId();
+
+  Handle(OpenGl_CappingPlaneResource) aPlaneRes;
+  if (!aContext->GetResource (aResId, aPlaneRes))
+  {
+    // share and register for release once the resource is no longer used
+    aPlaneRes = new OpenGl_CappingPlaneResource (thePlane);
+    aContext->ShareResource (aResId, aPlaneRes);
+  }
+
+  aPlaneRes->Update (aContext);
+
+  const OpenGl_AspectFace* aFaceAspect = theWorkspace->AspectFace (Standard_False);
+  const OpenGl_AspectFace* aPlaneAspect = aPlaneRes->AspectFace();
+  if (aPlaneAspect != NULL)
+  {
+    theWorkspace->SetAspectFace (aPlaneAspect);
+  }
+
+  // apply aspect for rendering
+  theWorkspace->AspectFace (Standard_True);
+
+  // set identity model matrix
+  const OpenGl_Matrix* aModelMatrix = theWorkspace->SetStructureMatrix (&OpenGl_IdentityMatrix);
+
+  glMultMatrixf ((const GLfloat*)aPlaneRes->Orientation());
+  glNormal3f (0.0f, 1.0f, 0.0f);
+  glEnableClientState (GL_VERTEX_ARRAY);
+  glVertexPointer (4, GL_FLOAT, 0, (GLfloat* )&THE_CAPPING_PLN_VERTS);
+  glEnableClientState (GL_TEXTURE_COORD_ARRAY);
+  glTexCoordPointer (4, GL_FLOAT, 0, (GLfloat*)&THE_CAPPING_PLN_TCOORD);
+  glDrawArrays (GL_TRIANGLES, 0, 12);
+  glDisableClientState (GL_VERTEX_ARRAY);
+  glDisableClientState (GL_TEXTURE_COORD_ARRAY);
+
+  theWorkspace->SetStructureMatrix (aModelMatrix);
+  theWorkspace->SetAspectFace (aFaceAspect);
+
+  // set delayed resource release
+  aPlaneRes.Nullify();
+  aContext->ReleaseResource (aResId, Standard_True);
+}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_CappingAlgo::Init()
+{
+  if (myIsInit)
+    return;
+
+  myRenderFilter = new OpenGl_CappingAlgoFilter();
+  myNoneCulling.CullingMode = TelCullNone;
+  myNoneCulling.Edge = 0;
+
+  myFrontCulling.CullingMode = TelCullBack;
+  myFrontCulling.Edge = 0;
+
+  myIsInit = Standard_True;
+}
+
+// =======================================================================
+// function : CanRender
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_CappingAlgoFilter::CanRender (const OpenGl_Element* theElement)
+{
+  const OpenGl_PrimitiveArray* aPArray =
+    dynamic_cast<const OpenGl_PrimitiveArray*> (theElement);
+  if (!aPArray)
+    return Standard_False;
+
+  switch (aPArray->PArray()->type)
+  {
+    case TelPolygonsArrayType :
+    case TelTrianglesArrayType :
+    case TelQuadranglesArrayType :
+    case TelTriangleStripsArrayType :
+    case TelQuadrangleStripsArrayType :
+    case TelTriangleFansArrayType :
+      return Standard_True;
+
+    default:
+      return Standard_False;
+  }
+}
diff --git a/src/OpenGl/OpenGl_CappingAlgo.hxx b/src/OpenGl/OpenGl_CappingAlgo.hxx
new file mode 100644 (file)
index 0000000..a51cfb5
--- /dev/null
@@ -0,0 +1,92 @@
+// Created on: 2013-09-05
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_CappingAlgo_H__
+#define _OpenGl_CappingAlgo_H__
+
+#include <OpenGl_RenderFilter.hxx>
+#include <OpenGl_Group.hxx>
+
+// Forward declaration
+class Handle(OpenGl_Workspace);
+class Handle(Graphic3d_ClipPlane);
+
+DEFINE_STANDARD_HANDLE (OpenGl_CappingAlgoFilter, OpenGl_RenderFilter)
+
+//! Capping surface rendering algorithm.
+class OpenGl_CappingAlgo
+{
+public:
+
+  //! Draw capping surfaces by OpenGl for the clipping planes
+  //! enabled in current context state. Depth buffer must be generated
+  //! for the passed groups.
+  //! @param theWorkspace [in] the GL workspace, context state.
+  //! @param theGroups [in] the group of primitives to be capped.
+  Standard_EXPORT static void RenderCapping (const Handle(OpenGl_Workspace)& theWorkspace,
+                                             const OpenGl_ListOfGroup& theGroups);
+
+  //! Render infinite capping plane.
+  //! @param theWorkspace [in] the GL workspace, context state.
+  //! @param thePlane [in] the graphical plane, for which the capping surface is rendered.
+  Standard_EXPORT static void RenderPlane (const Handle(OpenGl_Workspace)& theWorkspace,
+                                           const Handle(Graphic3d_ClipPlane)& thePlane);
+
+private:
+
+  //! Init algorithm.
+  static void Init();
+
+  //! @return capping algorithm rendering filter.
+  static const Handle(OpenGl_RenderFilter)& CappingFilter() { return myRenderFilter; }
+
+  //! @return face aspect for front face culling mode.
+  static const OpenGl_AspectFace* FrontCulling() { return &myFrontCulling; }
+
+  //! @return face aspect for none culling mode.
+  static const OpenGl_AspectFace* NoneCulling() { return &myNoneCulling; }
+
+private:
+
+  static Handle(OpenGl_RenderFilter) myRenderFilter;
+  static OpenGl_AspectFace myFrontCulling;
+  static OpenGl_AspectFace myNoneCulling;
+  static Standard_Boolean myIsInit;
+};
+
+//! Graphical capping rendering algorithm filter.
+//! Filters out everything excepth shaded primitives.
+class OpenGl_CappingAlgoFilter : public OpenGl_RenderFilter
+{
+public:
+
+  //! Default constructor.
+  OpenGl_CappingAlgoFilter() {}
+
+  //! Checks whether the element can be rendered or not.
+  //! @param theElement [in] the element to check.
+  //! @return True if element can be rendered.
+  virtual Standard_Boolean CanRender (const OpenGl_Element* theElement);
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_CappingAlgoFilter)
+};
+
+#endif
diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.cxx b/src/OpenGl/OpenGl_CappingPlaneResource.cxx
new file mode 100644 (file)
index 0000000..b7009c2
--- /dev/null
@@ -0,0 +1,171 @@
+// Created on: 2013-08-15
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OpenGl_CappingPlaneResource.hxx>
+#include <OpenGl_Context.hxx>
+#include <OpenGl_Vec.hxx>
+#include <Precision.hxx>
+
+IMPLEMENT_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_CappingPlaneResource, OpenGl_Resource)
+
+// =======================================================================
+// function : OpenGl_CappingPlaneResource
+// purpose  :
+// =======================================================================
+OpenGl_CappingPlaneResource::OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane)
+: myOrientation (OpenGl_IdentityMatrix),
+  myAspect (NULL),
+  myPlaneRoot (thePlane),
+  myEquationMod (0),
+  myAspectMod (0)
+{}
+
+// =======================================================================
+// function : OpenGl_CappingPlaneResource
+// purpose  :
+// =======================================================================
+OpenGl_CappingPlaneResource::~OpenGl_CappingPlaneResource()
+{
+  Release (NULL);
+}
+
+// =======================================================================
+// function : Update
+// purpose  :
+// =======================================================================
+void OpenGl_CappingPlaneResource::Update (const Handle(OpenGl_Context)& theContext)
+{
+  UpdateTransform();
+  UpdateAspect (theContext);
+}
+
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
+void OpenGl_CappingPlaneResource::Release (const OpenGl_Context* theContext)
+{
+  OpenGl_Element::Destroy (theContext, myAspect);
+  myEquationMod = 0;
+  myAspectMod   = 0;
+}
+
+// =======================================================================
+// function : UpdateAspect
+// purpose  :
+// =======================================================================
+void OpenGl_CappingPlaneResource::UpdateAspect (const Handle(OpenGl_Context)& theContext)
+{
+  Handle(Graphic3d_AspectFillArea3d) aCappingAsp = myPlaneRoot->CappingAspect();
+  if (myAspect != NULL && !aCappingAsp.IsNull())
+  {
+    if (myAspectMod == myPlaneRoot->MCountAspect())
+      return; // noting to update
+    
+    myAspect->Init (theContext, aCappingAsp);
+    myAspectMod = myPlaneRoot->MCountAspect();
+    return;
+  }
+
+  // no more used
+  if (myAspect != NULL && aCappingAsp.IsNull())
+  {
+    OpenGl_Element::Destroy (theContext, myAspect);
+    myAspectMod = myPlaneRoot->MCountAspect();
+    return;
+  }
+
+  // first created
+  if (myAspect == NULL && !aCappingAsp.IsNull())
+  {
+    myAspect = new OpenGl_AspectFace();
+    myAspect->Init (theContext, aCappingAsp);
+    myAspectMod = myPlaneRoot->MCountAspect();
+  }
+}
+
+// =======================================================================
+// function : UpdateTransform
+// purpose  :
+// =======================================================================
+void OpenGl_CappingPlaneResource::UpdateTransform()
+{
+  const Graphic3d_ClipPlane::Equation& anEquation = myPlaneRoot->GetEquation();
+  if (myEquationMod == myPlaneRoot->MCountEquation())
+  {
+    return; // nothing to update
+  }
+
+  // re-evaluate infinite plane transformation matrix
+  Standard_ShortReal N[3] = 
+    { (Standard_ShortReal)anEquation[0],
+      (Standard_ShortReal)anEquation[1],
+      (Standard_ShortReal)anEquation[2] };
+
+  Standard_ShortReal T[3] = 
+    { (Standard_ShortReal)(anEquation[0] * -anEquation[3]),
+      (Standard_ShortReal)(anEquation[1] * -anEquation[3]),
+      (Standard_ShortReal)(anEquation[2] * -anEquation[3]) };
+
+  Standard_ShortReal L[3] = { 0.0f, 0.0f, 0.0f };
+  Standard_ShortReal F[3] = { 0.0f, 0.0f, 0.0f };
+
+  // project plane normal onto OX to find left vector
+  Standard_ShortReal aConfusion = (Standard_ShortReal)Precision::Confusion();
+  Standard_ShortReal aProjLen = 
+    sqrt (  (Standard_ShortReal)(anEquation[0] * anEquation[0])
+          + (Standard_ShortReal)(anEquation[2] * anEquation[2]));
+  if (aProjLen < aConfusion)
+  {
+    L[0] = 1.0f;
+  }
+  else
+  {
+    L[0] =  N[2] / aProjLen;
+    L[2] = -N[0] / aProjLen;
+  }
+
+  // (-aLeft) x aNorm
+  F[0] = (-L[1])*N[2] - (-L[2])*N[1];
+  F[1] = (-L[2])*N[0] - (-L[0])*N[2];
+  F[2] = (-L[0])*N[1] - (-L[1])*N[0];
+
+  myOrientation.mat[0][0] = L[0];
+  myOrientation.mat[0][1] = L[1];
+  myOrientation.mat[0][2] = L[2];
+  myOrientation.mat[0][3] = 0.0f;
+
+  myOrientation.mat[1][0] = N[0];
+  myOrientation.mat[1][1] = N[1];
+  myOrientation.mat[1][2] = N[2];
+  myOrientation.mat[1][3] = 0.0f;
+
+  myOrientation.mat[2][0] = F[0];
+  myOrientation.mat[2][1] = F[1];
+  myOrientation.mat[2][2] = F[2];
+  myOrientation.mat[2][3] = 0.0f;
+
+  myOrientation.mat[3][0] = T[0];
+  myOrientation.mat[3][1] = T[1];
+  myOrientation.mat[3][2] = T[2];
+  myOrientation.mat[3][3] = 1.0f;
+
+  myEquationMod = myPlaneRoot->MCountEquation();
+}
diff --git a/src/OpenGl/OpenGl_CappingPlaneResource.hxx b/src/OpenGl/OpenGl_CappingPlaneResource.hxx
new file mode 100644 (file)
index 0000000..b66c039
--- /dev/null
@@ -0,0 +1,88 @@
+// Created on: 2013-08-15
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_CappingPlaneResource_H__
+#define _OpenGl_CappingPlaneResource_H__
+
+#include <OpenGl_Resource.hxx>
+#include <OpenGl_AspectFace.hxx>
+#include <OpenGl_Matrix.hxx>
+#include <Graphic3d_ClipPlane.hxx>
+
+class Handle(OpenGl_Context);
+
+DEFINE_STANDARD_HANDLE (OpenGl_CappingPlaneResource, OpenGl_Resource)
+
+//! Container of graphical resources for rendering capping plane
+//! associated to graphical clipping plane.
+//! This resource holds data necessary for OpenGl_CappingAlgo.
+//! This object is implemented as OpenGl resource for the following reasons:
+//! - one instance should be shared between contexts.
+//! - instance associated to Graphic3d_ClipPlane data by id.
+//! - should created and released within context (owns OpenGl elements and resources).
+class OpenGl_CappingPlaneResource : public OpenGl_Resource
+{
+public:
+
+  //! Constructor.
+  //! Create capping plane presentation associated to clipping plane data.
+  //! @param thePlane [in] the plane data.
+  Standard_EXPORT OpenGl_CappingPlaneResource (const Handle(Graphic3d_ClipPlane)& thePlane);
+
+  //! Destroy object.
+  Standard_EXPORT virtual ~OpenGl_CappingPlaneResource();
+
+  //! Update resource data in the passed context.
+  //! @param theContext [in] the context.
+  Standard_EXPORT void Update (const Handle(OpenGl_Context)& theContext);
+
+  //! Release associated OpenGl resources.
+  //! @param theContext [in] the resource context.
+  Standard_EXPORT void Release (const OpenGl_Context* theContext);
+
+  //! @return aspect face for rendering capping surface.
+  inline const OpenGl_AspectFace* AspectFace() const { return myAspect; }
+
+  //! @return evaluated orientation matrix to transform infinite plane.
+  inline const OpenGl_Matrix* Orientation() const { return &myOrientation; }
+
+private:
+
+  //! Update precomputed plane orientation matrix.
+  void UpdateTransform();
+
+  //! Update resources.
+  //! @param theContext [in] the context.
+  void UpdateAspect (const Handle(OpenGl_Context)& theContext);
+
+private:
+
+  OpenGl_Matrix               myOrientation;   //!< plane transformation matrix.
+  OpenGl_AspectFace*          myAspect;        //!< capping face aspect.
+  Handle(Graphic3d_ClipPlane) myPlaneRoot;     //!< parent clipping plane structure.
+  unsigned int                myEquationMod;   //!< modification counter for plane equation.
+  unsigned int                myAspectMod;     //!< modification counter for aspect.
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_CappingPlaneResource) // Type definition
+
+};
+
+#endif
diff --git a/src/OpenGl/OpenGl_ClippingState.cxx b/src/OpenGl/OpenGl_ClippingState.cxx
new file mode 100644 (file)
index 0000000..308adba
--- /dev/null
@@ -0,0 +1,248 @@
+// Created on: 2013-09-05
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#include <OpenGl_ClippingState.hxx>
+#include <OpenGl_GlCore11.hxx>
+
+namespace
+{
+  static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
+};
+
+// =======================================================================
+// function : OpenGl_ClippingState
+// purpose  :
+// =======================================================================
+OpenGl_ClippingState::OpenGl_ClippingState ()
+: myPlanes(),
+  myPlaneStates(),
+  myEmptyPlaneIds (new Aspect_GenId (GL_CLIP_PLANE0, GL_CLIP_PLANE5))
+{}
+
+// =======================================================================
+// function : Init
+// purpose  :
+// =======================================================================
+void OpenGl_ClippingState::Init (const Standard_Integer theMaxPlanes)
+{
+  myPlanes.Clear();
+  myPlaneStates.Clear();
+  Standard_Integer aLowerId = GL_CLIP_PLANE0;
+  Standard_Integer aUpperId = GL_CLIP_PLANE0 + theMaxPlanes - 1;
+  myEmptyPlaneIds = new Aspect_GenId (aLowerId, aUpperId);
+}
+
+// =======================================================================
+// function : Planes
+// purpose  :
+// =======================================================================
+Graphic3d_SetOfHClipPlane OpenGl_ClippingState::Planes() const
+{
+  Graphic3d_SetOfHClipPlane aRes;
+  OpenGl_MapOfContextPlanes::Iterator anIt (myPlanes);
+  for (; anIt.More(); anIt.Next())
+  {
+    aRes.Add (anIt.Key());
+  }
+
+  return aRes;
+}
+
+// =======================================================================
+// function : IsSet
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ClippingState::IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const
+{
+  return myPlanes.IsBound (thePlane);
+}
+
+// =======================================================================
+// function : Set
+// purpose  :
+// =======================================================================
+void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
+                                const Standard_Boolean theToEnable)
+{
+  Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
+  for (; aPlaneIt.More() && myEmptyPlaneIds->Available() > 0; aPlaneIt.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+    if (IsSet (aPlane))
+      return;
+
+    Standard_Integer anId = myEmptyPlaneIds->Next();
+    myPlanes.Bind (aPlane, anId);
+    myPlaneStates.Bind (aPlane, theToEnable);
+
+    const GLenum anOpenGlId = (GLenum)anId;
+    if (theToEnable)
+    {
+      glEnable (anOpenGlId);
+    }
+    else
+    {
+      glDisable (anOpenGlId);
+    }
+
+    glClipPlane (anOpenGlId, aPlane->GetEquation());
+  }
+}
+
+// =======================================================================
+// function : Set
+// purpose  :
+// =======================================================================
+void OpenGl_ClippingState::Set (const Graphic3d_SetOfHClipPlane& thePlanes,
+                                const OpenGl_Matrix* theViewMatrix,
+                                const Standard_Boolean theToEnable)
+{
+  GLint aMatrixMode;
+  glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
+
+  OpenGl_Matrix aCurrentMat;
+  glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)aCurrentMat.mat);
+
+  if (aMatrixMode != GL_MODELVIEW)
+  {
+    glMatrixMode (GL_MODELVIEW);
+  }
+
+  // load equation transform matrices
+  glLoadMatrixf ((theViewMatrix != NULL)
+    ? (const GLfloat*)theViewMatrix->mat
+    : (const GLfloat*)OpenGl_IdentityMatrix.mat);
+
+  Set (thePlanes, theToEnable);
+
+  // restore model-view matrix
+  glLoadMatrixf ((GLfloat*)aCurrentMat.mat);
+
+  // restore context matrix state
+  if (aMatrixMode != GL_MODELVIEW)
+  {
+    glMatrixMode (aMatrixMode);
+  }
+}
+
+// =======================================================================
+// function : Unset
+// purpose  :
+// =======================================================================
+void OpenGl_ClippingState::Unset (const Graphic3d_SetOfHClipPlane& thePlanes)
+{
+  Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
+  for (; aPlaneIt.More(); aPlaneIt.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aPlane = aPlaneIt.Value();
+    if (!IsSet (aPlane))
+      continue;
+
+    Standard_Integer anId = myPlanes.Find (aPlane);
+    myEmptyPlaneIds->Free (anId);
+    myPlanes.UnBind (aPlane);
+    myPlaneStates.UnBind (aPlane);
+
+    const GLenum anOpenGlId = (GLenum)anId;
+
+    glDisable (anOpenGlId);
+    glClipPlane (anOpenGlId, OpenGl_DefaultPlaneEq);
+  }
+}
+
+//
+//// =======================================================================
+//// function : SetPlane
+//// purpose  :
+//// =======================================================================
+//Standard_Boolean OpenGl_ClippingState::SetPlane (const Handle(Graphic3d_ClipPlane)& thePlane,
+//                                                 const Standard_Boolean theToEnable)
+//{
+//  if (myEmptyPlaneIds->Available() == 0)
+//    return Standard_False;
+//
+//  if (IsPlaneSet (thePlane))
+//    return Standard_True;
+//
+//  Standard_Integer aPlaneId = myEmptyPlaneIds->Next();
+//  myPlanes.Bind (thePlane, aPlaneId);
+//  myPlaneStates.Bind (thePlane, theToEnable);
+//  if (theToEnable)
+//    glEnable (aPlaneId);
+//  else
+//    glDisable (aPlaneId);
+//
+//  glClipPlane (aPlaneId, thePlane->GetEquation());
+//
+//  return Standard_True;
+//}
+
+//// =======================================================================
+//// function : UnsetPlane
+//// purpose  :
+//// =======================================================================
+//void OpenGl_ClippingState::UnsetPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
+//{
+//  if (!IsPlaneSet (thePlane))
+//    return;
+//
+//  Standard_Integer aPlaneId = myPlanes.Find (thePlane);
+//
+//  myEmptyPlaneIds->Free (aPlaneId);
+//  myPlanes.UnBind (thePlane);
+//  myPlaneStates.UnBind (thePlane);
+//
+//  glDisable (aPlaneId);
+//  glClipPlane (aPlaneId, OpenGl_DefaultPlaneEq);
+//}
+
+// =======================================================================
+// function : IsEnabled
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_ClippingState::IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const
+{
+  Standard_Boolean isSet;
+  return IsSet (thePlane)
+      && myPlaneStates.Find (thePlane, isSet)
+      && isSet;
+}
+
+// =======================================================================
+// function : SetEnabled
+// purpose  :
+// =======================================================================
+void OpenGl_ClippingState::SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane,
+                                       const Standard_Boolean theIsEnabled)
+{
+  if (!IsSet (thePlane))
+    return;
+
+  Standard_Boolean& aState = myPlaneStates.ChangeFind (thePlane);
+  if (theIsEnabled == aState)
+    return;
+
+  Standard_Integer aPlaneId = myPlanes.Find (thePlane);
+  if (theIsEnabled)
+    glEnable (aPlaneId);
+  else
+    glDisable (aPlaneId);
+
+  aState = theIsEnabled;
+}
diff --git a/src/OpenGl/OpenGl_ClippingState.hxx b/src/OpenGl/OpenGl_ClippingState.hxx
new file mode 100644 (file)
index 0000000..c52df31
--- /dev/null
@@ -0,0 +1,103 @@
+// Created on: 2013-09-05
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_ClippingState_H__
+#define _OpenGl_ClippingState_H__
+
+#include <Aspect_GenId.hxx>
+#include <Graphic3d_ClipPlane.hxx>
+#include <Graphic3d_SetOfHClipPlane.hxx>
+#include <NCollection_DataMap.hxx>
+#include <NCollection_Handle.hxx>
+#include <Standard_TypeDef.hxx>
+#include <OpenGl_Matrix.hxx>
+
+//! This class contains logics related to tracking and modification of clipping plane
+//! state for particular OpenGl context. It contains information about enabled
+//! clipping planes and provides method to change clippings in context. The methods
+//! should be executed within OpenGl context associated with instance of this
+//! class.
+class OpenGl_ClippingState
+{
+public:
+
+  //! Default constructor.
+  Standard_EXPORT OpenGl_ClippingState ();
+
+  //! Initialize.
+  //! @param theMaxPlanes [in] number of clipping planes supported by OpenGl context.
+  Standard_EXPORT void Init (const Standard_Integer theMaxPlanes);
+
+  //! @return sequence of set clipping planes.
+  Standard_EXPORT Graphic3d_SetOfHClipPlane Planes() const;
+
+  //! Check whether the clipping plane has been set for the current context state.
+  //! @param thePlane [in] the plane to check.
+  //! @return True if plane is set.
+  Standard_EXPORT Standard_Boolean IsSet (const Handle(Graphic3d_ClipPlane)& thePlane) const;
+
+  //! Set collection of clipping planes for available plane ids. Current model view matrix is used.
+  //! @param thePlanes [in] collection of planes.
+  //! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled.
+  Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes,
+                            const Standard_Boolean theToEnable = Standard_True);
+
+  //! Set collection of clipping planes for available plane ids. Identity matrix in case
+  //! if passed matrix pointer is NULL.
+  //! @param thePlanes [in] collection of planes.
+  //! @param theViewMatrix [in] view matrix to be used to define plane equation.
+  //! @param theToEnable [in] the boolean flag notifying whether the planes should be enabled.
+  Standard_EXPORT void Set (const Graphic3d_SetOfHClipPlane& thePlanes,
+                            const OpenGl_Matrix* theViewMatrix,
+                            const Standard_Boolean theToEnable = Standard_True);
+
+  //! Unset and disable collection of clipping planes.
+  //! @param thePlanes [in] the plane to deactivate.
+  Standard_EXPORT void Unset (const Graphic3d_SetOfHClipPlane& thePlanes);
+
+  //! Check whether the clipping plane has been set and enabled for the current context state.
+  //! @param thePlane [in] the plane to check.
+  //! @return True if plane is enabled.
+  Standard_EXPORT Standard_Boolean IsEnabled (const Handle(Graphic3d_ClipPlane)& thePlane) const;
+
+  //! Change enabled / disabled state of the clipping plane.
+  //! @param thePlane [in] the plane to change the state.
+  //! @param theIsEnabled [in] the flag indicating whether the plane should be enabled or not.
+  //! @return False if plane is not set for the context.
+  Standard_EXPORT void SetEnabled (const Handle(Graphic3d_ClipPlane)& thePlane, const Standard_Boolean theIsEnabled);
+
+private:
+
+  typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), Standard_Integer> OpenGl_MapOfContextPlanes;
+  typedef NCollection_DataMap<Handle(Graphic3d_ClipPlane), Standard_Boolean> OpenGl_MapOfPlaneStates;
+  typedef NCollection_Handle<Aspect_GenId> OpenGl_EmptyPlaneIds;
+
+  OpenGl_MapOfContextPlanes      myPlanes;          //!< map of clip planes bound for the ids
+  OpenGl_MapOfPlaneStates        myPlaneStates;     //!< map of clip planes state (enabled/disabled).
+  OpenGl_EmptyPlaneIds           myEmptyPlaneIds;   //!< generator of empty ids
+
+private:
+
+  //! Copying allowed only within Handles
+  OpenGl_ClippingState            (const OpenGl_ClippingState& );
+  OpenGl_ClippingState& operator= (const OpenGl_ClippingState& );
+
+};
+
+#endif
index 09cd4a5..765f9bc 100644 (file)
@@ -64,6 +64,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
 namespace
 {
   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
+  static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
 };
 
 // =======================================================================
@@ -91,10 +92,12 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
   mySharedResources (new OpenGl_ResourcesMap()),
   myDelayed         (new OpenGl_DelayReleaseMap()),
   myReleaseQueue    (new OpenGl_ResourcesQueue()),
+  myClippingState (),
   myGlLibHandle (NULL),
   myGlCore20 (NULL),
-  myAnisoMax   (1),
   myMaxTexDim  (1024),
+  myMaxClipPlanes (6),
+  myAnisoMax   (1),
   myGlVerMajor (0),
   myGlVerMinor (0),
   myIsFeedback (Standard_False),
@@ -163,6 +166,15 @@ Standard_Integer OpenGl_Context::MaxTextureSize() const
 }
 
 // =======================================================================
+// function : MaxClipPlanes
+// purpose  :
+// =======================================================================
+Standard_Integer OpenGl_Context::MaxClipPlanes() const
+{
+  return myMaxClipPlanes;
+}
+
+// =======================================================================
 // function : Share
 // purpose  :
 // =======================================================================
@@ -594,12 +606,16 @@ void OpenGl_Context::init()
   atiMem  = CheckExtension ("GL_ATI_meminfo");
   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
 
+  // get number of maximum clipping planes
+  glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
   if (extAnis)
   {
     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
   }
 
+  myClippingState.Init (myMaxClipPlanes);
+
   // initialize debug context extension
   if (CheckExtension ("GL_ARB_debug_output"))
   {
index ecdc69c..52fc999 100644 (file)
@@ -26,6 +26,7 @@
 #include <Aspect_RenderingContext.hxx>
 #include <Handle_OpenGl_Context.hxx>
 #include <NCollection_DataMap.hxx>
+#include <NCollection_Map.hxx>
 #include <NCollection_Handle.hxx>
 #include <NCollection_Queue.hxx>
 #include <OpenGl_Caps.hxx>
@@ -33,6 +34,7 @@
 #include <Standard_Transient.hxx>
 #include <TCollection_AsciiString.hxx>
 #include <Handle_OpenGl_Context.hxx>
+#include <OpenGl_ClippingState.hxx>
 
 //! Forward declarations
 struct OpenGl_GlCore12;
@@ -238,12 +240,26 @@ public:
   //! Clean up the delayed release queue.
   Standard_EXPORT void ReleaseDelayed();
 
+  //! @return tool for management of clippings within this context.
+  inline OpenGl_ClippingState& ChangeClipping() { return myClippingState; }
+
+  //! @return tool for management of clippings within this context.
+  inline const OpenGl_ClippingState& Clipping() const { return myClippingState; }
+
+public:
+
   //! @return maximum degree of anisotropy texture filter
   Standard_EXPORT Standard_Integer MaxDegreeOfAnisotropy() const;
 
   //! @return value for GL_MAX_TEXTURE_SIZE
   Standard_EXPORT Standard_Integer MaxTextureSize() const;
 
+  //! Get maximum number of clip planes supported by OpenGl.
+  //! This value is implementation dependant. At least 6
+  //! planes should be supported by OpenGl (see specs).
+  //! @return value for GL_MAX_CLIP_PLANES
+  Standard_EXPORT Standard_Integer MaxClipPlanes() const;
+
 private:
 
   //! Wrapper to system function to retrieve GL function pointer by name.
@@ -306,15 +322,19 @@ private: // context info
   Handle(OpenGl_DelayReleaseMap) myDelayed;         //!< shared resources for delayed release
   Handle(OpenGl_ResourcesQueue)  myReleaseQueue;    //!< queue of resources for delayed clean up
 
+  OpenGl_ClippingState myClippingState; //!< state of clip planes
+
   void*            myGlLibHandle;   //!< optional handle to GL library
   OpenGl_GlCore20* myGlCore20;      //!< common structure for GL core functions upto 2.0
   Standard_Integer myAnisoMax;      //!< maximum level of anisotropy texture filter
   Standard_Integer myMaxTexDim;     //!< value for GL_MAX_TEXTURE_SIZE
+  Standard_Integer myMaxClipPlanes; //!< value for GL_MAX_CLIP_PLANES
   Standard_Integer myGlVerMajor;    //!< cached GL version major number
   Standard_Integer myGlVerMinor;    //!< cached GL version minor number
   Standard_Boolean myIsFeedback;    //!< flag indicates GL_FEEDBACK mode
   Standard_Boolean myIsInitialized; //!< flag indicates initialization state
 
+
 private:
 
   //! Copying allowed only within Handles
index b900f28..44fa1dc 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <Handle_OpenGl_Context.hxx>
 #include <Handle_OpenGl_Workspace.hxx>
+#include <OpenGl_RenderFilter.hxx>
 
 //! Base interface for drawable elements.
 class OpenGl_Element
@@ -50,6 +51,30 @@ public:
     theElement = NULL;
   }
 
+public:
+
+  //! Render element if it passes the filtering procedure. This method should
+  //! be used for elements which can be used in scope of rendering algorithms.
+  //! E.g. elements of groups during recursive rendering.
+  //! If render filter is null, pure rendering is performed.
+  //! @param theWorkspace [in] the rendering workspace.
+  //! @param theFilter [in] the rendering filter to check whether the element
+  //! should be rendered or not.
+  //! @return True if element passes the filering check and is rendered.
+  inline Standard_Boolean
+    RenderFiltered (const Handle(OpenGl_Workspace)& theWorkspace,
+                    const Handle(OpenGl_RenderFilter)& theFilter) const
+  {
+    if (!theFilter.IsNull() && !theFilter->CanRender (this))
+    {
+      return Standard_False;
+    }
+
+    Render (theWorkspace);
+
+    return Standard_True;
+  }
+
 protected:
 
   Standard_EXPORT virtual ~OpenGl_Element();
index a3ae77f..f2f86c9 100644 (file)
@@ -152,7 +152,8 @@ public:
   Standard_EXPORT void Redraw (const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACUnderLayer, const Aspect_CLayer2d& ACOverLayer, const Standard_Integer x = 0, const Standard_Integer y = 0, const Standard_Integer width = 0, const Standard_Integer height = 0);
   Standard_EXPORT void RemoveView (const Graphic3d_CView& ACView);
   Standard_EXPORT void SetLight (const Graphic3d_CView& ACView);
-  Standard_EXPORT void SetPlane (const Graphic3d_CView& ACView);
+  Standard_EXPORT void SetClipPlanes (const Graphic3d_CView& theCView);
+  Standard_EXPORT void SetClipPlanes (const Graphic3d_CStructure& theCStructure);
   Standard_EXPORT void SetVisualisation (const Graphic3d_CView& ACView);
   Standard_EXPORT void TransformStructure (const Graphic3d_CStructure& ACStructure);
   Standard_EXPORT void Transparency (const Graphic3d_CView& ACView, const Standard_Boolean AFlag);
index 4e91e47..5b18377 100755 (executable)
@@ -448,11 +448,22 @@ void OpenGl_GraphicDriver::SetLight (const Graphic3d_CView& ACView)
     aCView->View->SetLights(ACView.Context);
 }
 
-void OpenGl_GraphicDriver::SetPlane (const Graphic3d_CView& ACView)
+void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CView& theCView)
 {
-  const OpenGl_CView *aCView = (const OpenGl_CView *)ACView.ptrView;
+  const OpenGl_CView *aCView = (const OpenGl_CView *)theCView.ptrView;
   if (aCView)
-    aCView->View->SetClippingPlanes(ACView.Context);
+  {
+    aCView->View->SetClipPlanes (theCView.Context.ClipPlanes);
+  }
+}
+
+void OpenGl_GraphicDriver::SetClipPlanes (const Graphic3d_CStructure& theCStructure)
+{
+  OpenGl_Structure* aStructure = (OpenGl_Structure *)theCStructure.ptrStructure;
+  if (aStructure)
+  {
+    aStructure->SetClipPlanes (theCStructure.ClipPlanes);
+  }
 }
 
 void OpenGl_GraphicDriver::SetVisualisation (const Graphic3d_CView& ACView)
index b6f81ad..a647151 100644 (file)
 #include <OpenGl_PrimitiveArray.hxx>
 #include <OpenGl_Workspace.hxx>
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : OpenGl_Group
+// purpose  :
+// =======================================================================
 OpenGl_Group::OpenGl_Group ()
 : myAspectLine(NULL),
   myAspectFace(NULL),
@@ -33,13 +35,19 @@ OpenGl_Group::OpenGl_Group ()
 {
 }
 
+// =======================================================================
+// function : ~OpenGl_Group
+// purpose  :
+// =======================================================================
 OpenGl_Group::~OpenGl_Group()
 {
   Release (Handle(OpenGl_Context)());
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectLine
+// purpose  :
+// =======================================================================
 void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext,
                                   const Standard_Boolean theIsGlobal)
 {
@@ -57,8 +65,10 @@ void OpenGl_Group::SetAspectLine (const CALL_DEF_CONTEXTLINE& theContext,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectFace
+// purpose  :
+// =======================================================================
 void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
                                   const CALL_DEF_CONTEXTFILLAREA& theAspect,
                                   const Standard_Boolean          theIsGlobal)
@@ -79,8 +89,10 @@ void OpenGl_Group::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectMarker
+// purpose  :
+// =======================================================================
 void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
                                     const CALL_DEF_CONTEXTMARKER& theAspect,
                                     const Standard_Boolean theIsGlobal)
@@ -101,8 +113,10 @@ void OpenGl_Group::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectText
+// purpose  :
+// =======================================================================
 void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
                                   const Standard_Boolean theIsGlobal)
 {
@@ -120,8 +134,10 @@ void OpenGl_Group::SetAspectText (const CALL_DEF_CONTEXTTEXT& theContext,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : AddElement
+// purpose  :
+// =======================================================================
 void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
 {
   OpenGl_ElementNode *node = new OpenGl_ElementNode();
@@ -133,34 +149,25 @@ void OpenGl_Group::AddElement (const TelType AType, OpenGl_Element *AElem )
   myLast = node;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
 {
   // Is rendering in ADD or IMMEDIATE mode?
   const Standard_Boolean isImmediate = (theWorkspace->NamedStatus & (OPENGL_NS_ADD | OPENGL_NS_IMMEDIATE)) != 0;
+  const Handle(OpenGl_RenderFilter)& aFilter = theWorkspace->GetRenderFilter();
 
   // Setup aspects
   const OpenGl_AspectLine*   aBackAspectLine   = theWorkspace->AspectLine   (Standard_False);
   const OpenGl_AspectFace*   aBackAspectFace   = theWorkspace->AspectFace   (Standard_False);
   const OpenGl_AspectMarker* aBackAspectMarker = theWorkspace->AspectMarker (Standard_False);
   const OpenGl_AspectText*   aBackAspectText   = theWorkspace->AspectText   (Standard_False);
-  if (myAspectLine)
-  {
-    theWorkspace->SetAspectLine (myAspectLine);
-  }
-  if (myAspectFace)
-  {
-    theWorkspace->SetAspectFace (myAspectFace);
-  }
-  if (myAspectMarker)
-  {
-    theWorkspace->SetAspectMarker (myAspectMarker);
-  }
-  if (myAspectText)
-  {
-    theWorkspace->SetAspectText (myAspectText);
-  }
+  Standard_Boolean isLineSet   = myAspectLine   && myAspectLine->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isFaceSet   = myAspectFace   && myAspectFace->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isMarkerSet = myAspectMarker && myAspectMarker->RenderFiltered (theWorkspace, aFilter);
+  Standard_Boolean isTextSet   = myAspectText   && myAspectText->RenderFiltered (theWorkspace, aFilter);
 
   // Render group elements
   for (OpenGl_ElementNode* aNodeIter = myFirst; aNodeIter != NULL; aNodeIter = aNodeIter->next)
@@ -177,24 +184,32 @@ void OpenGl_Group::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
           glDepthMask (GL_FALSE);
         }
 
-        aNodeIter->elem->Render (theWorkspace);
+        aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
         break;
       }
       default:
       {
-        aNodeIter->elem->Render (theWorkspace);
+        aNodeIter->elem->RenderFiltered (theWorkspace, aFilter);
         break;
       }
     }
   }
 
   // Restore aspects
-  theWorkspace->SetAspectLine   (aBackAspectLine);
-  theWorkspace->SetAspectFace   (aBackAspectFace);
-  theWorkspace->SetAspectMarker (aBackAspectMarker);
-  theWorkspace->SetAspectText   (aBackAspectText);
+  if (isLineSet)
+    theWorkspace->SetAspectLine (aBackAspectLine);
+  if (isFaceSet)
+    theWorkspace->SetAspectFace (aBackAspectFace);
+  if (isMarkerSet)
+    theWorkspace->SetAspectMarker (aBackAspectMarker);
+  if (isTextSet)
+    theWorkspace->SetAspectText (aBackAspectText);
 }
 
+// =======================================================================
+// function : Release
+// purpose  :
+// =======================================================================
 void OpenGl_Group::Release (const Handle(OpenGl_Context)& theGlCtx)
 {
   // Delete elements
index 4d4d9c7..47ca2da 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _OpenGl_Group_Header
 #define _OpenGl_Group_Header
 
+#include <NCollection_List.hxx>
 #include <InterfaceGraphic_Graphic3d.hxx>
 
 #include <OpenGl_Element.hxx>
 
 #include <OpenGl_tsm.hxx>
 
+class OpenGl_Group;
+
+typedef NCollection_List<const OpenGl_Group*     > OpenGl_ListOfGroup;
+
 struct OpenGl_ElementNode
 {
   TelType type;
index 85dec05..cf9f875 100644 (file)
@@ -32,4 +32,13 @@ struct OpenGl_Matrix
 Standard_EXPORT void OpenGl_Multiplymat3 (OpenGl_Matrix *c, const OpenGl_Matrix *a, const OpenGl_Matrix *b);
 Standard_EXPORT void OpenGl_Transposemat3 (OpenGl_Matrix *c, const OpenGl_Matrix *a);
 
+const static OpenGl_Matrix OpenGl_IdentityMatrix =
+{
+  // mat[4][4]
+  { { 1.0f, 0.0f, 0.0f, 0.0f },
+    { 0.0f, 1.0f, 0.0f, 0.0f },
+    { 0.0f, 0.0f, 1.0f, 0.0f },
+    { 0.0f, 0.0f, 0.0f, 1.0f } }
+};
+
 #endif //OpenGl_Matrix_Header
old mode 100755 (executable)
new mode 100644 (file)
similarity index 77%
rename from src/Graphic3d/Graphic3d_CPlane.cxx
rename to src/OpenGl/OpenGl_RenderFilter.cxx
index f1c1e6b..2b79cb5
@@ -1,4 +1,6 @@
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Created on: 2013-07-25
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
+#include <OpenGl_RenderFilter.hxx>
 
-#include <Graphic3d_CPlane.hxx>
-
-const Handle(Standard_Type)& TYPE(Graphic3d_CPlane)
-{
-  static Handle(Standard_Type) _atype =
-    new Standard_Type ("Graphic3d_CPlane", sizeof (Graphic3d_CPlane));
-  return _atype;
-}
+IMPLEMENT_STANDARD_HANDLE(OpenGl_RenderFilter, Standard_Transient)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_RenderFilter, Standard_Transient)
diff --git a/src/OpenGl/OpenGl_RenderFilter.hxx b/src/OpenGl/OpenGl_RenderFilter.hxx
new file mode 100644 (file)
index 0000000..196fe69
--- /dev/null
@@ -0,0 +1,47 @@
+// Created on: 2013-07-25
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _OpenGl_RenderFilter_H__
+#define _OpenGl_RenderFilter_H__
+
+#include <Standard_DefineHandle.hxx>
+#include <Standard_Transient.hxx>
+
+DEFINE_STANDARD_HANDLE (OpenGl_RenderFilter, Standard_Transient)
+
+class OpenGl_Element;
+
+//! Base class for defining element rendering filters.
+//! This class can be used in pair with advance rendering passes, and for 
+//! disabling rendering (setting up) graphical aspects.
+class OpenGl_RenderFilter : public Standard_Transient
+{
+public:
+
+  //! Checks whether the element can be rendered or not.
+  //! @param theElement [in] the element to check.
+  //! @return True if element can be rendered.
+  virtual Standard_Boolean CanRender (const OpenGl_Element* theElement) = 0;
+
+public:
+
+  DEFINE_STANDARD_RTTI(OpenGl_RenderFilter)
+};
+
+#endif
index 47a436e..16a9ff9 100644 (file)
@@ -24,7 +24,8 @@
 #include <OpenGl_Workspace.hxx>
 #include <OpenGl_Vec.hxx>
 #include <OpenGl_View.hxx>
-
+#include <OpenGl_CappingAlgo.hxx>
+#include <OpenGl_Context.hxx>
 #include <OpenGl_telem_util.hxx>
 
 //! Auxiliary class for bounding box presentation
@@ -111,6 +112,10 @@ public:
 
 /*----------------------------------------------------------------------*/
 
+// =======================================================================
+// function : call_util_transpose_mat
+// purpose  :
+// =======================================================================
 static void call_util_transpose_mat (float tmat[16], float mat[4][4])
 {
   int i, j;
@@ -120,8 +125,10 @@ static void call_util_transpose_mat (float tmat[16], float mat[4][4])
       tmat[j*4+i] = mat[i][j];
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : OpenGl_Structure
+// purpose  :
+// =======================================================================
 OpenGl_Structure::OpenGl_Structure ()
 : myTransformation(NULL),
   myTransPers(NULL),
@@ -136,8 +143,10 @@ OpenGl_Structure::OpenGl_Structure ()
 {
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ~OpenGl_Structure
+// purpose  :
+// =======================================================================
 OpenGl_Structure::~OpenGl_Structure()
 {
   Release (Handle(OpenGl_Context)());
@@ -145,8 +154,10 @@ OpenGl_Structure::~OpenGl_Structure()
   delete myTransPers;       myTransPers       = NULL;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetTransformation
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetTransformation(const float *AMatrix)
 {
   if (!myTransformation)
@@ -155,8 +166,10 @@ void OpenGl_Structure::SetTransformation(const float *AMatrix)
   matcpy( myTransformation->mat, AMatrix );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetTransformPersistence
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTENCE &ATransPers)
 {
   if (!myTransPers)
@@ -168,8 +181,10 @@ void OpenGl_Structure::SetTransformPersistence(const CALL_DEF_TRANSFORM_PERSISTE
   myTransPers->pointZ = ATransPers.Point.z;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectLine
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
 {
   if (!myAspectLine)
@@ -177,8 +192,10 @@ void OpenGl_Structure::SetAspectLine (const CALL_DEF_CONTEXTLINE &AContext)
   myAspectLine->SetContext( AContext );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectFace
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
                                       const CALL_DEF_CONTEXTFILLAREA& theAspect)
 {
@@ -189,8 +206,10 @@ void OpenGl_Structure::SetAspectFace (const Handle(OpenGl_Context)&   theCtx,
   myAspectFace->Init (theCtx, theAspect);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectMarker
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
                                         const CALL_DEF_CONTEXTMARKER& theAspect)
 {
@@ -201,8 +220,10 @@ void OpenGl_Structure::SetAspectMarker (const Handle(OpenGl_Context)& theCtx,
   myAspectMarker->Init (theCtx, theAspect);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetAspectText
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
 {
   if (!myAspectText)
@@ -210,8 +231,10 @@ void OpenGl_Structure::SetAspectText (const CALL_DEF_CONTEXTTEXT &AContext)
   myAspectText->SetContext( AContext );
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetHighlightBox
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
                                         const CALL_DEF_BOUNDBOX&      theBoundBox)
 {
@@ -234,8 +257,10 @@ void OpenGl_Structure::SetHighlightBox (const Handle(OpenGl_Context)& theGlCtx,
   myHighlightBox->AddElement (TelParray, aBndBoxPrs);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ClearHighlightBox
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx)
 {
   if (myHighlightBox != NULL)
@@ -244,8 +269,10 @@ void OpenGl_Structure::ClearHighlightBox (const Handle(OpenGl_Context)& theGlCtx
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : SetHighlightColor
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx,
                                           const Standard_ShortReal R,
                                           const Standard_ShortReal G,
@@ -263,8 +290,10 @@ void OpenGl_Structure::SetHighlightColor (const Handle(OpenGl_Context)& theGlCtx
   myHighlightColor->rgb[3] = 1.F;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : ClearHighlightColor
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlCtx)
 {
   ClearHighlightBox(theGlCtx);
@@ -272,16 +301,20 @@ void OpenGl_Structure::ClearHighlightColor (const Handle(OpenGl_Context)& theGlC
   myHighlightColor = NULL;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Connect
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Connect (const OpenGl_Structure *AStructure)
 {
   Disconnect (AStructure);
   myConnected.Append(AStructure);
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Disconnect
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
 {
   OpenGl_ListOfStructure::Iterator its(myConnected);
@@ -297,8 +330,10 @@ void OpenGl_Structure::Disconnect (const OpenGl_Structure *AStructure)
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : AddGroup
+// purpose  :
+// =======================================================================
 OpenGl_Group * OpenGl_Structure::AddGroup ()
 {
   // Create new group
@@ -307,8 +342,10 @@ OpenGl_Group * OpenGl_Structure::AddGroup ()
   return g;
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : RemoveGroup
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
                                     const OpenGl_Group*           theGroup)
 {
@@ -325,8 +362,10 @@ void OpenGl_Structure::RemoveGroup (const Handle(OpenGl_Context)& theGlCtx,
   }
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Clear
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
 {
   // Release groups
@@ -338,8 +377,10 @@ void OpenGl_Structure::Clear (const Handle(OpenGl_Context)& theGlCtx)
   myGroups.Clear();
 }
 
-/*----------------------------------------------------------------------*/
-
+// =======================================================================
+// function : Render
+// purpose  :
+// =======================================================================
 void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
 {
   // Process the structure only if visible
@@ -415,6 +456,25 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
     its.Next();
   }
 
+  // Set up plane equations for non-structure transformed global model-view matrix
+  const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
+
+  // Collect planes which should be turned on for structure
+  Graphic3d_SetOfHClipPlane aPlanesOn;
+  Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
+  for (; aPlaneIt.More(); aPlaneIt.Next())
+  {
+    const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value();
+    if (aUserPln->IsOn())
+      aPlanesOn.Add (aUserPln);
+  }
+
+  // set structure clipping planes
+  if (aPlanesOn.Size() > 0)
+  {
+    aContext->ChangeClipping().Set (aPlanesOn, AWorkspace->ViewMatrix());
+  }
+
   // Render groups
   OpenGl_ListOfGroup::Iterator itg(myGroups);
   while (itg.More())
@@ -423,6 +483,15 @@ void OpenGl_Structure::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
     itg.Next();
   }
 
+  // Render cappings for structure groups
+  OpenGl_CappingAlgo::RenderCapping (AWorkspace, myGroups);
+
+  // unset structure clipping planes
+  if (aPlanesOn.Size() > 0)
+  {
+    aContext->ChangeClipping().Unset (aPlanesOn);
+  }
+
   // Restore highlight color
   AWorkspace->HighlightColor = highlight_color;
 
@@ -514,7 +583,6 @@ void OpenGl_Structure::ReleaseGlResources (const Handle(OpenGl_Context)& theGlCt
 //function : SetZLayer
 //purpose  :
 //=======================================================================
-
 void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
 {
   myZLayer = theLayerIndex;
@@ -524,7 +592,6 @@ void OpenGl_Structure::SetZLayer (const Standard_Integer theLayerIndex)
 //function : GetZLayer
 //purpose  :
 //=======================================================================
-
 Standard_Integer OpenGl_Structure::GetZLayer () const
 {
   return myZLayer;
index 978ace2..e4c4b55 100644 (file)
 #include <OpenGl_Group.hxx>
 #include <OpenGl_Matrix.hxx>
 
+#include <Graphic3d_SetOfHClipPlane.hxx>
+
 class OpenGl_Structure;
 
 typedef NCollection_List<const OpenGl_Structure* > OpenGl_ListOfStructure;
-typedef NCollection_List<const OpenGl_Group*     > OpenGl_ListOfGroup;
 
 class OpenGl_Structure : public OpenGl_Element
 {
@@ -68,6 +69,8 @@ public:
 
   void SetNamedStatus (const Standard_Integer aStatus) { myNamedStatus = aStatus; }
 
+  void SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes) { myClipPlanes = thePlanes; }
+
   void Connect (const OpenGl_Structure *astructure);
   void Disconnect (const OpenGl_Structure *astructure);
 
@@ -97,6 +100,11 @@ protected:
 
   virtual ~OpenGl_Structure();
 
+  //! Draw capping surfaces by h/w for the clipping planes
+  //! enabled for the structure.
+  //! @param theWorkspace [in] the GL workspace, context state.
+  void DrawCapping (const Handle(OpenGl_Workspace)& theWorkspace) const;
+
 protected:
 
   //Structure_LABBegin
@@ -116,6 +124,7 @@ protected:
 
   OpenGl_ListOfStructure     myConnected;
   OpenGl_ListOfGroup         myGroups;
+  Graphic3d_SetOfHClipPlane  myClipPlanes;
 
 public:
 
index d181b75..b9fff66 100644 (file)
@@ -245,30 +245,6 @@ void OpenGl_View::SetLights (const CALL_DEF_VIEWCONTEXT &AContext)
 
 /*----------------------------------------------------------------------*/
 
-//call_togl_setplane
-void OpenGl_View::SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext)
-{
-  // clear clipping planes information
-  myClippingPlanes.Clear();
-  // update information
-  int i = 0;
-  for (; i < AContext.NbActivePlane; i++)
-  {
-    const CALL_DEF_PLANE &aCPlane = AContext.ActivePlane[i];
-    if ( aCPlane.Active && aCPlane.PlaneId > 0 )
-    {
-      OPENGL_CLIP_REP aPlane;
-      aPlane.equation[0] = aCPlane.CoefA;
-      aPlane.equation[1] = aCPlane.CoefB;
-      aPlane.equation[2] = aCPlane.CoefC;
-      aPlane.equation[3] = aCPlane.CoefD;
-      myClippingPlanes.Append( aPlane );
-    }
-  }
-}
-
-/*----------------------------------------------------------------------*/
-
 //call_togl_setvisualisation
 void OpenGl_View::SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext)
 {
index 9598f65..15593c7 100644 (file)
@@ -37,6 +37,7 @@
 
 #include <Graphic3d_CView.hxx>
 #include <Graphic3d_CGraduatedTrihedron.hxx>
+#include <Graphic3d_SetOfHClipPlane.hxx>
 #include <Visual3d_TypeOfSurfaceDetail.hxx>
 
 #include <OpenGl_telem_view.hxx>
@@ -72,12 +73,6 @@ struct OPENGL_EXTRA_REP
   Tfloat  scaleFactors[3];
 };
 
-struct OPENGL_CLIP_REP
-{
-  Standard_Real equation[4];
-  DEFINE_STANDARD_ALLOC
-};
-
 struct OPENGL_ZCLIP
 {
   struct {
@@ -117,7 +112,7 @@ class OpenGl_View : public MMgt_TShared
   void SetBackfacing (const Standard_Integer AMode);
   void SetLights (const CALL_DEF_VIEWCONTEXT &AContext);
   void SetAntiAliasing (const Standard_Boolean AMode) { myAntiAliasing = AMode; }
-  void SetClippingPlanes (const CALL_DEF_VIEWCONTEXT &AContext);
+  void SetClipPlanes (const Graphic3d_SetOfHClipPlane &thePlanes) { myClipPlanes = thePlanes; }
   void SetVisualisation (const CALL_DEF_VIEWCONTEXT &AContext);
 
   void SetClipLimit (const Graphic3d_CView& theCView);
@@ -222,11 +217,11 @@ public:
   //Tint        active_status;
 
   OPENGL_ZCLIP   myZClip;
-  NCollection_List<OPENGL_CLIP_REP> myClippingPlanes;
-
   OPENGL_EXTRA_REP myExtra;
   //}
 
+  Graphic3d_SetOfHClipPlane myClipPlanes;
+  
   OPENGL_FOG myFog;
   OpenGl_Trihedron*          myTrihedron;
   OpenGl_GraduatedTrihedron* myGraduatedTrihedron;
index a9faf46..5a054c3 100644 (file)
@@ -638,10 +638,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
                           const Aspect_CLayer2d& ACOverLayer)
 {
   // Store and disable current clipping planes
-  GLint maxplanes;
-  glGetIntegerv(GL_MAX_CLIP_PLANES, &maxplanes);
-  const GLenum lastid = GL_CLIP_PLANE0 + maxplanes;
-  OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[maxplanes];
+  const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
+  const Standard_Integer aMaxClipPlanes = aContext->MaxClipPlanes();
+  const GLenum lastid = GL_CLIP_PLANE0 + aMaxClipPlanes;
+  OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[aMaxClipPlanes];
   OPENGL_CLIP_PLANE *ptrPlane = oldPlanes;
   GLenum planeid = GL_CLIP_PLANE0;
   for ( ; planeid < lastid; planeid++, ptrPlane++ )
@@ -652,8 +652,10 @@ void OpenGl_View::Render (const Handle(OpenGl_PrinterContext)& thePrintContext,
       glDisable( planeid );
       ptrPlane->isEnabled = GL_TRUE;
     }
-       else
+    else
+    {
       ptrPlane->isEnabled = GL_FALSE;
+    }
   }
 
   /////////////////////////////////////////////////////////////////////////////
@@ -987,55 +989,42 @@ D = -[Px,Py,Pz] dot |Nx|
 
   // Apply clipping planes
   {
-    // Define starting plane id
-    planeid = GL_CLIP_PLANE0;
-
-    GLdouble equation[4];
-
     if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
     {
-      // Apply front and back clipping planes
-      GLfloat mat[4][4];
-      glMatrixMode( GL_MODELVIEW );
-      glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
-      glLoadIdentity();
+      Graphic3d_SetOfHClipPlane aZClipping;
 
       const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
 
       if ( myZClip.Back.IsOn )
       {
         const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
-        equation[0] = 0.0;  /* Nx */
-        equation[1] = 0.0;  /* Ny */
-        equation[2] = 1.0;  /* Nz */
-        equation[3] = -back; /* P dot N */
-        glClipPlane( planeid, equation );
-        glEnable( planeid );
-        planeid++;
+        const Graphic3d_ClipPlane::Equation aBack(0.0, 0.0, 1.0, -back);
+        aZClipping.Add (new Graphic3d_ClipPlane (aBack));
       }
 
       if ( myZClip.Front.IsOn )
       {
         const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
-        equation[0] = 0.0;  /* Nx */
-        equation[1] = 0.0;  /* Ny */
-        equation[2] = -1.0; /* Nz */
-        equation[3] = front; /* P dot N */
-        glClipPlane( planeid, equation );
-        glEnable( planeid );
-        planeid++;
+        const Graphic3d_ClipPlane::Equation aFront (0.0, 0.0, -1.0, front);
+        aZClipping.Add (new Graphic3d_ClipPlane (aFront));
       }
 
-      glLoadMatrixf( (GLfloat *) mat );
+      aContext->ChangeClipping().Set (aZClipping, &OpenGl_IdentityMatrix);
     }
 
     // Apply user clipping planes
-    NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
-    for ( ; planeIter.More(); planeIter.Next() )
+    Graphic3d_SetOfHClipPlane aPlanesOn;
+    Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (myClipPlanes);
+    for (; aPlaneIt.More(); aPlaneIt.Next())
     {
-      glClipPlane( planeid, planeIter.Value().equation );
-      glEnable( planeid );
-      planeid++;
+      const Handle(Graphic3d_ClipPlane)& aUserPln = aPlaneIt.Value();
+      if (aUserPln->IsOn ())
+        aPlanesOn.Add (aUserPln);
+    }
+
+    if (aPlanesOn.Size() > 0)
+    {
+      aContext->ChangeClipping().Set (aPlanesOn);
     }
   }
 
@@ -1122,9 +1111,8 @@ D = -[Px,Py,Pz] dot |Nx|
   // and invoking optional callbacks
   AWorkspace->ResetAppliedAspect();
 
-  // Disable current clipping planes
-  for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
-    glDisable( planeid );
+  // Unset clip planes managed by driver
+  aContext->ChangeClipping().Unset (aContext->Clipping().Planes());
 
   // display global trihedron
   if (myTrihedron != NULL)
index a0c453c..5045cae 100644 (file)
@@ -29,6 +29,7 @@
 #include <OpenGl_FrameBuffer.hxx>
 #include <OpenGl_Texture.hxx>
 #include <OpenGl_Workspace.hxx>
+#include <OpenGl_Element.hxx>
 
 #include <Graphic3d_TextureParams.hxx>
 
index 351127a..5caff56 100644 (file)
@@ -49,6 +49,7 @@
 #include <OpenGl_NamedStatus.hxx>
 #include <OpenGl_PrinterContext.hxx>
 #include <OpenGl_TextParam.hxx>
+#include <OpenGl_RenderFilter.hxx>
 
 #include <Handle_OpenGl_View.hxx>
 #include <Handle_OpenGl_Texture.hxx>
@@ -58,6 +59,7 @@ class OpenGl_AspectMarker;
 class OpenGl_AspectText;
 class OpenGl_FrameBuffer;
 class OpenGl_Structure;
+class OpenGl_Element;
 class Image_PixMap;
 
 //! Reprepsents window with GL context.
@@ -167,6 +169,28 @@ public:
   Standard_EXPORT Handle(OpenGl_Texture) EnableTexture (const Handle(OpenGl_Texture)&          theTexture,
                                                         const Handle(Graphic3d_TextureParams)& theParams = NULL);
 
+  //! Set filter for restricting rendering of particular elements.
+  //! Filter can be applied for rendering passes used by recursive
+  //! rendering algorithms for rendering elements of groups.
+  //! @param theFilter [in] the filter instance.
+  inline void SetRenderFilter (const Handle(OpenGl_RenderFilter)& theFilter)
+  {
+    myRenderFilter = theFilter; 
+  }
+
+  //! Get rendering filter.
+  //! @return filter instance.
+  inline const Handle(OpenGl_RenderFilter)& GetRenderFilter() const 
+  { 
+    return myRenderFilter; 
+  }
+
+  //! @return applied view matrix.
+  inline const OpenGl_Matrix* ViewMatrix() const { return ViewMatrix_applied; }
+
+  //! @return applied model structure matrix.
+  inline const OpenGl_Matrix* ModelMatrix() const { return StructureMatrix_applied; }
+
 protected:
 
   void CopyBuffers (const Standard_Boolean theFrontToBack);
@@ -202,6 +226,7 @@ protected: //! @name protected fields
 
 protected: //! @name fields related to status
 
+  Handle(OpenGl_RenderFilter) myRenderFilter;
   Handle(OpenGl_Texture) myTextureBound;    //!< currently bound texture (managed by OpenGl_AspectFace and OpenGl_View environment texture)
   const OpenGl_AspectLine *AspectLine_set, *AspectLine_applied;
   const OpenGl_AspectFace *AspectFace_set, *AspectFace_applied;
index 50c2781..97dd501 100755 (executable)
@@ -63,6 +63,8 @@ uses
     Transformation        from Geom,
     ListOfInteger         from TColStd,
     Location              from TopLoc, 
+    ClipPlane_Handle      from Graphic3d,
+    SetOfHClipPlane       from Graphic3d,
     --   ABD 29/10/04  Transform Persistence of Presentation( pan, zoom, rotate )
     TransModeFlags        from Graphic3d, 
     Pnt                   from gp, 
@@ -249,11 +251,46 @@ is
      returns Integer from Standard is static;
    ---Purpose: Get ID of Z layer. If no presentations of object is displayed,
    -- and layer ID is unavailable, the -1 value is returned.
+
+   AddClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual;
+   ---Purpose: Adds clip plane for graphical clipping for all display mode
+   -- presentations. The composition of clip planes truncates the rendering
+   -- space to convex volume. Please be aware that number of supported
+   -- clip plane is limited. The planes which exceed the limit are ignored.
+   -- Besides of this, some planes can be already set in view where the object
+   -- is shown: the number of these planes should be substracted from limit
+   -- to predict the maximum possible number of object clipping planes.
+   -- @param thePlane [in] the clip plane to be appended to map of clip planes.
+
+   RemoveClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual;
+   ---Purpose: Removes previously added clip plane.
+   -- @param thePlane [in] the clip plane to be removed from map of clip planes.
+
+   SetClipPlanes (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is virtual;
+   ---Purpose: Set clip planes for graphical clipping for all display mode presentations.
+   -- The composition of clip planes truncates the rendering space to convex
+   -- volume. Please be aware that number of supported clip plane is limited.
+   -- The planes which exceed the limit are ignored. Besides of this, some
+   -- planes can be already set in view where the object is shown: the number 
+   -- of these planes should be substracted from limit to predict the maximum
+   -- possible number of object clipping planes.
+
+   GetClipPlanes (me) returns SetOfHClipPlane from Graphic3d;
+   ---C++: inline
+   ---C++: return const&
+   ---Purpose: Get clip planes.
+   -- @return set of previously added clip planes for all display mode presentations.
+
+   UpdateClipping (me : mutable) is virtual protected;
+   ---Purpose: General virtual method for internal update of presentation state
+   -- when some modifications on list of clip planes occurs. Base 
+   -- implementation propagate clip planes to every presentation.
+
 fields
     myPresentations: Presentations from PrsMgr is protected;
     myTypeOfPresentation3d: TypeOfPresentation3d from PrsMgr is protected;
     myLocation  : Location from TopLoc is protected; 
+    myClipPlanes : SetOfHClipPlane from Graphic3d is protected;
     --myTransformPersistence  :  TransModeFlags  from  Graphic3d; 
     myTransformPersistence  :  CTransPersStruct  from  Graphic3d;
 
index 8348004..a6ad5cc 100755 (executable)
@@ -36,7 +36,6 @@
 //function : PrsMgr_PresentableObject
 //purpose  : 
 //=======================================================================
-
 PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentation3d aTypeOfPresentation3d)
      :myPresentations(),myTypeOfPresentation3d(aTypeOfPresentation3d)
 {
@@ -46,25 +45,29 @@ PrsMgr_PresentableObject::PrsMgr_PresentableObject(const PrsMgr_TypeOfPresentati
   myTransformPersistence.Point.z = 0.0;
 }
 
-
 //=======================================================================
 //function : Fill
 //purpose  : 
 //=======================================================================
-void PrsMgr_PresentableObject::Fill(const Handle(PrsMgr_PresentationManager)& aPresentationManager,
-                                   const Handle(PrsMgr_Presentation)& aPresentation,
-                                   const Standard_Integer aMode) {
-  if (aPresentation->DynamicType() == STANDARD_TYPE(PrsMgr_Presentation3d)) {
-    Compute(((Handle(PrsMgr_PresentationManager3d)&)aPresentationManager),((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation(),aMode);
-    UpdateLocation(((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation());
-    Handle(Graphic3d_Structure) aStruct = Handle(Graphic3d_Structure)::DownCast( ((Handle(PrsMgr_Presentation3d)&)aPresentation)->Presentation() );
-    if ( !aStruct.IsNull() ) {
-      aStruct->SetTransformPersistence( GetTransformPersistenceMode(), GetTransformPersistencePoint() );
-    }
+void PrsMgr_PresentableObject::Fill (const Handle(PrsMgr_PresentationManager)& aPresentationManager,
+                                     const Handle(PrsMgr_Presentation)& aPresentation,
+                                     const Standard_Integer aMode)
+{
+  if (aPresentation->DynamicType() == STANDARD_TYPE (PrsMgr_Presentation3d))
+  {
+    Handle(PrsMgr_PresentationManager3d) aPrsMgr3d =
+      (Handle(PrsMgr_PresentationManager3d)&)aPresentationManager;
+    Handle(PrsMgr_Presentation3d) aPrs3d = 
+      (Handle(PrsMgr_Presentation3d)&)aPresentation;
+    Handle(Prs3d_Presentation) aStruct3d = aPrs3d->Presentation();
+
+    Compute (aPrsMgr3d, aStruct3d, aMode);
+    UpdateLocation (aStruct3d);
+    aStruct3d->SetClipPlanes (myClipPlanes);
+    aStruct3d->SetTransformPersistence (GetTransformPersistenceMode(), GetTransformPersistencePoint());
   }
 }
 
-
 //=======================================================================
 //function : Compute
 //purpose  : 
@@ -75,6 +78,7 @@ void PrsMgr_PresentableObject::Compute(const Handle(PrsMgr_PresentationManager3d
 {
   Standard_NotImplemented::Raise("cannot compute in a 3d visualizer");
 }
+
 //=======================================================================
 //function : Compute
 //purpose  : 
@@ -84,6 +88,7 @@ void PrsMgr_PresentableObject::Compute(const Handle(Prs3d_Projector)& /*aProject
 {
   Standard_NotImplemented::Raise("cannot compute under a specific projector");
 }
+
 //=======================================================================
 //function : Compute
 //purpose  : 
@@ -116,11 +121,11 @@ void PrsMgr_PresentableObject::Update (const Standard_Boolean AllModes) {
     }
   }
 }
+
 //=======================================================================
 //function : Update
 //purpose  : 
 //=======================================================================
-
 void PrsMgr_PresentableObject::Update (const Standard_Integer aMode, const Standard_Boolean ClearOther) {
   Standard_Integer l = myPresentations.Length();
   for (Standard_Integer i=1; i <= l; i++) {
@@ -149,11 +154,11 @@ void PrsMgr_PresentableObject::Update (const Standard_Integer aMode, const Stand
   }
 
 }
+
 //=======================================================================
 //function : Presentations
 //purpose  : 
 //=======================================================================
-
 PrsMgr_Presentations& PrsMgr_PresentableObject::Presentations() {
   return myPresentations;
 }
@@ -162,18 +167,15 @@ PrsMgr_Presentations& PrsMgr_PresentableObject::Presentations() {
 //function : HasLocation
 //purpose  : 
 //=======================================================================
-
 Standard_Boolean PrsMgr_PresentableObject::HasLocation() const 
 {
-  return !Location().IsIdentity();}
-
-
+  return !Location().IsIdentity();
+}
 
 //=======================================================================
 //function : SetToUpdate
 //purpose  : 
 //=======================================================================
-
 void PrsMgr_PresentableObject::SetToUpdate(const Standard_Integer aMode)
 {
   for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){
@@ -181,6 +183,11 @@ void PrsMgr_PresentableObject::SetToUpdate(const Standard_Integer aMode)
       myPresentations(IP).Presentation()->SetUpdateStatus(Standard_True);
   }
 }
+
+//=======================================================================
+//function : SetToUpdate
+//purpose  :
+//=======================================================================
 void PrsMgr_PresentableObject::SetToUpdate()
 {
   for(Standard_Integer IP =1; IP<=myPresentations.Length();IP++){
@@ -213,7 +220,6 @@ void PrsMgr_PresentableObject::ToBeUpdated(TColStd_ListOfInteger& OutList) const
 //function : SetTypeOfPresentation
 //purpose  : 
 //=======================================================================
-
 void PrsMgr_PresentableObject::SetTypeOfPresentation(const PrsMgr_TypeOfPresentation3d aType)
 {
   myTypeOfPresentation3d = aType;
@@ -258,6 +264,10 @@ void PrsMgr_PresentableObject::ResetLocation()
   myLocation = aLoc;
 }
 
+//=======================================================================
+//function : UpdateLocation
+//purpose  :
+//=======================================================================
 void PrsMgr_PresentableObject::UpdateLocation()
 {
   if(!HasLocation()) return;
@@ -271,12 +281,10 @@ void PrsMgr_PresentableObject::UpdateLocation()
   }
 }
 
-
 //=======================================================================
 //function : UpdateLocation
 //purpose  : 
 //=======================================================================
-
 void PrsMgr_PresentableObject::UpdateLocation(const Handle(Prs3d_Presentation)& P)
 {
   if(myLocation.IsIdentity()) return;
@@ -363,3 +371,63 @@ Standard_Integer PrsMgr_PresentableObject::GetZLayer
 
   return -1;
 }
+
+// =======================================================================
+// function : AddClipPlane
+// purpose  :
+// =======================================================================
+void PrsMgr_PresentableObject::AddClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
+{
+  myClipPlanes.Add (thePlane);
+
+  UpdateClipping(); // process changes
+}
+
+// =======================================================================
+// function : RemoveClipPlane
+// purpose  :
+// =======================================================================
+void PrsMgr_PresentableObject::RemoveClipPlane (const Handle(Graphic3d_ClipPlane)& thePlane)
+{
+  myClipPlanes.Remove (thePlane);
+
+  UpdateClipping(); // process changes
+}
+
+// =======================================================================
+// function : SetClipPlanes
+// purpose  :
+// =======================================================================
+void PrsMgr_PresentableObject::SetClipPlanes (const Graphic3d_SetOfHClipPlane& thePlanes)
+{
+  myClipPlanes = thePlanes;
+
+  UpdateClipping();
+}
+
+// =======================================================================
+// function : UpdateClipping
+// purpose  :
+// =======================================================================
+void PrsMgr_PresentableObject::UpdateClipping()
+{
+  // affect generated structures
+  for (Standard_Integer aPrsIt = 1; aPrsIt <= myPresentations.Length(); ++aPrsIt)
+  {
+    // pass over presentation manager 3d mechanism right to the structures -
+    // we do not interested in display mode collections.
+    const PrsMgr_ModedPresentation& aModedPrs = myPresentations (aPrsIt);
+
+    Handle(PrsMgr_Presentation3d) aPrs = 
+      Handle(PrsMgr_Presentation3d)::DownCast (aModedPrs.Presentation());
+
+    if (aPrs.IsNull())
+      continue;
+
+    Handle(Prs3d_Presentation) aStruct3d = aPrs->Presentation();
+    if (aStruct3d.IsNull())
+      continue;
+
+    aStruct3d->SetClipPlanes (myClipPlanes);
+  }
+}
index b056ee7..3edbbe7 100755 (executable)
@@ -25,3 +25,8 @@ inline PrsMgr_TypeOfPresentation3d PrsMgr_PresentableObject::TypeOfPresentation3
 
 inline const TopLoc_Location& PrsMgr_PresentableObject::Location() const
 {return myLocation;}
+
+inline const Graphic3d_SetOfHClipPlane& PrsMgr_PresentableObject::GetClipPlanes() const
+{
+  return myClipPlanes;
+}
index f77883d..1685155 100644 (file)
@@ -32,6 +32,7 @@
 #include <GeomInt_IntSS.hxx>
 #include <BRepBuilderAPI_MakeEdge.hxx>
 #include <Standard_ErrorHandler.hxx>
+#include <Graphic3d_ClipPlane.hxx>
 #include <tcl.h>
 
 #include <fstream>
@@ -683,97 +684,9 @@ static Standard_Integer BUC60574(Draw_Interpretor& di, Standard_Integer /*n*/, c
 #include <BRepAlgoAPI_Fuse.hxx>
 #include <BRepAlgo_Fuse.hxx>
 
-#include <V3d_Plane.hxx>
 #include <V3d_View.hxx>
 #include <gce_MakePln.hxx>
 
-static Standard_Integer BUC60698(Draw_Interpretor& di, Standard_Integer argc, const char ** a)
-{
-  if(argc > 2) {
-    di << "Usage : " << a[0] << " [BRepAlgoAPI/BRepAlgo = 1/0]" << "\n";
-    return 1;
-  }
-  Standard_Boolean IsBRepAlgoAPI = Standard_True;
-  if (argc == 2) {
-    Standard_Integer IsB = Draw::Atoi(a[1]);
-    if (IsB != 1) {
-      IsBRepAlgoAPI = Standard_False;
-#if ! defined(BRepAlgo_def01)
-//      di << "Error: There is not BRepAlgo_Fuse class" << "\n";
-//      return 1;
-#endif
-    }
-  }
-  
-  Handle(AIS_InteractiveContext) myAISContext = ViewerTest::GetAISContext();
-  if(myAISContext.IsNull()) {
-    di << "use 'vinit' command before " << a[0] << "\n";
-    return -1;
-  }
-  TopoDS_Solid box = BRepPrimAPI_MakeBox(1,1,1).Solid();
-  TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(0.5,0.5,0.5),0.6).Shape();
-
-//#if ! defined(BRepAlgoAPI_def01)
-//  TopoDS_Shape fuse = BRepAlgoAPI_Fuse(box,sphere).Shape();
-//#else
-//  TopoDS_Shape fuse = BRepAlgo_Fuse(box,sphere).Shape();
-//#endif
-
-  TopoDS_Shape fuse;
-  if (IsBRepAlgoAPI) {
-    di << "fuse = BRepAlgoAPI_Fuse(box,sphere).Shape()" <<"\n";
-    fuse = BRepAlgoAPI_Fuse(box,sphere).Shape();
-  } else {
-    di << "fuse = BRepAlgo_Fuse(box,sphere).Shape()" <<"\n";
-    fuse = BRepAlgo_Fuse(box,sphere).Shape();
-  }
-
-  Handle_AIS_Shape theAISShape = new AIS_Shape(fuse);
-  myAISContext->Display(theAISShape);
-  di.Eval("vfit");
-  gp_Pln thegpPln = gce_MakePln(gp_Pnt(0.5,0.5,0.5),gp_Dir(0,0,1));
-  Standard_Real A,B,C,D;
-  thegpPln.Coefficients(A,B,C,D);
-  Handle_V3d_Plane thePlane = new V3d_Plane(A,B,C,D);
-  myAISContext->CurrentViewer()->AddPlane (thePlane); // add to defined planes list
-  for (myAISContext->CurrentViewer()->InitActiveViews();
-       myAISContext->CurrentViewer()->MoreActiveViews ();
-       myAISContext->CurrentViewer()->NextActiveViews ()) {
-    try {
-      OCC_CATCH_SIGNALS
-      myAISContext->CurrentViewer()->ActiveView()->SetPlaneOn(thePlane);
-    }
-    catch(Standard_Failure) {
-      di << "SetPlaneOn catched 1" << "\n";
-    }
-#ifdef WNT
-    catch(...) {
-      di << "SetPlaneOn catched 1" << "\n";
-    }
-#endif
-  }//ActiveView loop
-  for (myAISContext->CurrentViewer()->InitDefinedViews();
-       myAISContext->CurrentViewer()->MoreDefinedViews ();
-       myAISContext->CurrentViewer()->NextDefinedViews ()) {
-    try {
-      OCC_CATCH_SIGNALS
-      myAISContext->CurrentViewer()->DefinedView()->SetPlaneOn(thePlane);
-    }
-    catch(Standard_Failure) {
-      di << "SetPlaneOn catched 1" << "\n";
-    }
-#ifdef WNT
-    catch(...) {
-      di << "SetPlaneOn catched 2" << "\n";
-    }
-#endif
-  }//DefinedView loop
-  myAISContext->UpdateCurrentViewer();
-  myAISContext->OpenLocalContext();
-  myAISContext->ActivateStandardMode(TopAbs_FACE);
-  return 0;
-}
-
 static Standard_Integer BUC60699(Draw_Interpretor& di, Standard_Integer /*n*/, const char ** a)
 {
   
@@ -2239,8 +2152,6 @@ void QABugs::Commands_3(Draw_Interpretor& theCommands) {
   theCommands.Add("PRO19626","ksection resultat shell1 shell2 NbPntMax Toler3d Toler2d RelativeTol",__FILE__,ksection,group);  
   theCommands.Add("BUC60574","BUC60574 ",__FILE__,BUC60574,group);
 
-  theCommands.Add("BUC60698","BUC60698 [BRepAlgoAPI/BRepAlgo = 1/0]",__FILE__,BUC60698,group);
-
   theCommands.Add("BUC60699","BUC60699 ",__FILE__,BUC60699,group);
   theCommands.Add("GER61394","GER61394 [1/0]",__FILE__,GER61394,group);
   theCommands.Add("GER61351","GER61351 name/object name/r g b/object r g b",__FILE__,setcolor,group);
index d249386..42ad63a 100755 (executable)
@@ -193,23 +193,6 @@ is
     --          2d point <X,Y>.
     is virtual;
 
-    DepthMin(me) returns Real from Standard;
-    ---Purpose: Returns the minimum depth value (if clipping plane defined).
-    ---         Should be used when call ::Shoot() to compute eyeline.
-    ---C++: inline
-
-    DepthMax(me) returns Real from Standard;
-    ---Purpose: Returns the maximum depth value (if clipping plane defined).
-    ---         Should be used when call ::Shoot() to compute eyeline.
-    ---C++: inline
-
-    DepthMinMax(me : mutable;
-                theDepthMin : in Real from Standard;
-                theDepthMax : in Real from Standard);
-    ---Purpose: Setup the min/max depth values (doesn't affect
-    ---         projection functionality itself).
-    ---         Should be used when call ::Shoot() to compute eyeline.
-
     Transform(me; P : in out Pnt from gp;
                   T : GTrsf from gp)
     ---C++: inline
@@ -230,7 +213,5 @@ fields
     myInvTrsf    : GTrsf   from gp is protected;
 
     myView       : View    from V3d;
-    myDepthMin   : Real    from Standard;
-    myDepthMax   : Real    from Standard;
 
 end Projector;
index 3a897e9..1d42e4c 100755 (executable)
@@ -44,9 +44,7 @@
 Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
 : myPersp(aViou->Type()==V3d_PERSPECTIVE),
   myFocus(aViou->Focale()),
-  myView(aViou),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myView(aViou)
 {
   Standard_Real Xat,Yat,Zat,XUp,YUp,ZUp,DX,DY,DZ;
   //Standard_Boolean Pers=Standard_False;
@@ -72,9 +70,7 @@ Select3D_Projector::Select3D_Projector(const Handle(V3d_View)& aViou)
 
 Select3D_Projector::Select3D_Projector()
 : myPersp(Standard_False),
-  myFocus(0),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myFocus(0)
 {
   Scaled();
 }
@@ -86,9 +82,7 @@ Select3D_Projector::Select3D_Projector()
 
 Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
 : myPersp(Standard_False),
-  myFocus(0),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myFocus(0)
 {
   myScaledTrsf.SetTransformation(CS);
   myGTrsf.SetTrsf(myScaledTrsf);
@@ -103,9 +97,7 @@ Select3D_Projector::Select3D_Projector (const gp_Ax2& CS)
 Select3D_Projector::Select3D_Projector (const gp_Ax2& CS,
                                         const Standard_Real Focus)
 : myPersp(Standard_True),
-  myFocus(Focus),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myFocus(Focus)
 {
   myScaledTrsf.SetTransformation(CS);
   myGTrsf.SetTrsf(myScaledTrsf);
@@ -122,9 +114,7 @@ Select3D_Projector::Select3D_Projector (const gp_Trsf& T,
                                         const Standard_Real Focus)
 : myPersp(Persp),
   myFocus(Focus),
-  myScaledTrsf(T),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myScaledTrsf(T)
 {
   myGTrsf.SetTrsf(myScaledTrsf);
   Scaled();
@@ -140,9 +130,7 @@ Select3D_Projector::Select3D_Projector (const gp_GTrsf& GT,
                                         const Standard_Real Focus)
 : myPersp(Persp),
   myFocus(Focus),
-  myGTrsf(GT),
-  myDepthMin(-Precision::Infinite()),
-  myDepthMax( Precision::Infinite())
+  myGTrsf(GT)
 {
   Scaled();
 }
@@ -463,10 +451,3 @@ void Select3D_Projector::SetView(const Handle(V3d_View)& aViou)
   Scaled();
 
 }
-
-void Select3D_Projector::DepthMinMax (const Standard_Real theDepthMin,
-                                      const Standard_Real theDepthMax)
-{
-  myDepthMin = theDepthMin;
-  myDepthMax = theDepthMax;
-}
index a424272..6710e1d 100755 (executable)
@@ -126,13 +126,3 @@ inline void Select3D_Projector::Transform (gp_Pnt& Pnt, const gp_GTrsf& T) const
   T.Transforms(xyz);
   Pnt = gp_Pnt(xyz);
 }
-
-inline Standard_Real Select3D_Projector::DepthMin() const
-{
-  return myDepthMin;
-}
-
-inline Standard_Real Select3D_Projector::DepthMax() const
-{
-  return myDepthMax;
-}
index b47d4a7..8bfbee9 100755 (executable)
@@ -35,6 +35,7 @@ uses
     Lin              from gp,
     EntityOwner      from SelectBasics,
     ListOfBox2d      from SelectBasics,
+    PickArgs         from SelectBasics,
     Array1OfPnt2d    from TColgp,
     Location         from TopLoc
 
@@ -71,17 +72,16 @@ is
 
     GetConnected(me:mutable;aLocation: Location from TopLoc)
     returns SensitiveEntity from Select3D is redefined static;
-    
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is static;
-       ---Level: Public 
-       ---Purpose: 
-       --          
-    
+
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
+
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
              aTol: Real from Standard)
@@ -97,7 +97,7 @@ is
     
    
     ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
+    returns Real from Standard;
 
     Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual;
 
index c2cf79a..8945fa1 100755 (executable)
@@ -65,8 +65,6 @@ Select3D_SensitiveEntity(OwnerId)
 void Select3D_SensitiveBox::
 Project(const Handle(Select3D_Projector)& aProj)
 {
-  Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
-
   if(HasLocation())
   {
     Bnd_Box B = mybox3d.Transformed(Location().Transformation());
@@ -103,15 +101,20 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveBox::GetConnected(const TopLo
 // Function: Matches
 // Purpose :
 //==================================================
-Standard_Boolean Select3D_SensitiveBox::
-Matches(const Standard_Real X, 
-        const Standard_Real Y, 
-        const Standard_Real aTol, 
-        Standard_Real& DMin)
+
+Standard_Boolean Select3D_SensitiveBox::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                 Standard_Real& theMatchDMin,
+                                                 Standard_Real& theMatchDepth)
 {
-  Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-  DMin=0.;
-  
+  // check that sensitive box passes by depth
+  Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
+  if (thePickArgs.IsClipped (aDepth))
+  {
+    return Standard_False;
+  }
+
+  theMatchDMin = 0.0;
+  theMatchDepth = aDepth;
   return Standard_True;
 }
 
index 31baa52..53e6cce 100755 (executable)
@@ -34,6 +34,7 @@ uses
     Lin             from gp,
     EntityOwner     from SelectBasics,
     ListOfBox2d     from SelectBasics,
+    PickArgs        from SelectBasics,
     Circle          from Geom,
     Array1OfPnt     from TColgp,
     HArray1OfPnt    from TColgp,
@@ -95,12 +96,14 @@ is
         -- If the length of apolyg3d is more then 1, the first point of apolyg3d 
         -- must be equal to the last point of apolyg3d. 
 
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is static;
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -117,9 +120,16 @@ is
         ---Level: Public 
     
 
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
-    
+    ComputeDepth (me;
+                  thePickLine : Lin from gp;
+                  theDetectedIndex : Integer from Standard)
+    returns Real from Standard;
+    ---Level: Public
+    ---Purpose: Compute depth of sensitive circle for the detected sub-part.
+    -- @param thePickLine [in] the picking line.
+    -- @param theDetectedIndex [in] index of the detected sub-part.
+    -- @return depth on the picking line.
+
     ArrayBounds(me;Low,Up:in out Integer);
     
     GetPoint3d(me;rank:Integer) returns Pnt from gp;
@@ -142,7 +152,6 @@ is
 fields
 
     myFillStatus    : Boolean;
-    myDetectedIndex : Integer from Standard; -- used for depth...
     myCenter2D      : Pnt2d from Select3D; -- used for Matches()
     myCenter3D      : Pnt from Select3D; -- used for Matches()
     myCircle        : Circle from Geom;
index 66288e7..aebb297 100755 (executable)
@@ -72,7 +72,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
                          const Standard_Integer NbPoints):
 Select3D_SensitivePoly(OwnerId, S3D_GetCircleNBPoints(TheCircle,NbPoints)),
 myFillStatus(FilledCircle),
-myDetectedIndex(-1),
 myCircle(TheCircle),
 mystart(0),
 myend(0)
@@ -129,7 +128,6 @@ Select3D_SensitiveCircle(const Handle(SelectBasics_EntityOwner)& OwnerId,
                          const Standard_Integer NbPoints):
 Select3D_SensitivePoly(OwnerId, S3D_GetArcNBPoints(TheCircle,NbPoints)),
 myFillStatus(FilledCircle),
-myDetectedIndex(-1),
 myCircle(TheCircle),
 mystart(u1),
 myend(u2)
@@ -186,7 +184,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
                                                    const Standard_Boolean FilledCircle):
 Select3D_SensitivePoly(OwnerId, Thepolyg3d),
 myFillStatus(FilledCircle),
-myDetectedIndex(-1),
 mystart(0),
 myend(0)
 {
@@ -206,7 +203,6 @@ Select3D_SensitiveCircle::Select3D_SensitiveCircle(const Handle(SelectBasics_Ent
                                                    const Standard_Boolean FilledCircle):
 Select3D_SensitivePoly(OwnerId, Thepolyg3d),
 myFillStatus(FilledCircle),
-myDetectedIndex(-1),
 mystart(0),
 myend(0)
 {
@@ -221,13 +217,13 @@ myend(0)
 //purpose  :
 //=======================================================================
 
-Standard_Boolean Select3D_SensitiveCircle::
-Matches(const Standard_Real X,
-        const Standard_Real Y,
-        const Standard_Real aTol,
-        Standard_Real& DMin)
+Standard_Boolean Select3D_SensitiveCircle::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                    Standard_Real& theMatchDMin,
+                                                    Standard_Real& theMatchDepth)
 {
   Standard_Integer aSize = mypolyg.Size();
+  Standard_Integer aDetectedIndex = -1;
+  gp_XY aPickXY (thePickArgs.X(), thePickArgs.Y());
   if (aSize != 1)
   {
     Standard_Boolean Found = Standard_False;
@@ -241,15 +237,19 @@ Matches(const Standard_Real X,
           Select3D_SensitiveTriangle::Status(mypolyg.Pnt2d(anIndex),
                                              mypolyg.Pnt2d(anIndex+1),
                                              mypolyg.Pnt2d(anIndex+2),
-                                             gp_XY(X,Y),aTol,DMin);
+                                             aPickXY, thePickArgs.Tolerance(),
+                                             theMatchDMin);
         Found = (TheStat != 2);
-        if(Found) myDetectedIndex = anIndex;
+        if (Found)
+        {
+          aDetectedIndex = anIndex;
+        }
+
         anIndex += 2;
       }
     }
     else
     {
-      myDetectedIndex =-1;
       Standard_Real Xmin,Ymin,Xmax,Ymax;
 
       // Get coordinates of the bounding box
@@ -259,32 +259,47 @@ Matches(const Standard_Real X,
       // Fill anArrayOf2dPnt with points from mypolig2d
       Points2D(anArrayOf2dPnt);
 
-      CSLib_Class2d anInOutTool(anArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
+      CSLib_Class2d anInOutTool (anArrayOf2dPnt,
+                                 thePickArgs.Tolerance(),
+                                 thePickArgs.Tolerance(),
+                                 Xmin, Ymin, Xmax, Ymax);
 
       // Method SiDans returns the status :
       //  1 - the point is inside the circle
       //  0 - the point is on the circle
       // -1 - the point is outside the circle
-      Standard_Integer aStat = anInOutTool.SiDans(gp_Pnt2d(X,Y));
+      Standard_Integer aStat = anInOutTool.SiDans (gp_Pnt2d (aPickXY));
       if(aStat != -1)
       {
         // Compute DMin (a distance between the center and the point)
-        DMin = gp_XY(myCenter2D.x - X, myCenter2D.y - Y).Modulus();
-        Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-        return Standard_True;
+        theMatchDMin = gp_XY (myCenter2D.x - aPickXY.X(), myCenter2D.y - aPickXY.Y()).Modulus();
+
+        theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
+
+        return !thePickArgs.IsClipped (theMatchDepth);
       }
+
       return Standard_False;
     }
-    if(!Found)
-      myDetectedIndex=-1;
-    else
-      Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-    return Found;
+
+    if (Found)
+    {
+      theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
+
+      return !thePickArgs.IsClipped (theMatchDepth);
+    }
+
+    return Standard_False;
   }
+
   // Circle degenerates into point
-  DMin = gp_Pnt2d(X, Y).Distance(mypolyg.Pnt2d(0));
-  if (DMin <= aTol*SensitivityFactor())
-    return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+  theMatchDMin = gp_Pnt2d(aPickXY).Distance(mypolyg.Pnt2d(0));
+  if (theMatchDMin <= thePickArgs.Tolerance() * SensitivityFactor())
+  {
+    theMatchDepth = ComputeDepth (thePickArgs.PickLine(), aDetectedIndex);
+
+    return !thePickArgs.IsClipped (theMatchDepth);
+  }
 
   return Standard_False;
 }
@@ -301,7 +316,6 @@ Matches(const Standard_Real XMin,
         const Standard_Real YMax,
         const Standard_Real aTol)
 {
-  myDetectedIndex =-1;
   Bnd_Box2d abox;
   abox.Update(Min(XMin,XMax),Min(YMin,YMax),Max(XMin,XMax),Max(YMin,YMax));
   abox.Enlarge(aTol);
@@ -324,7 +338,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly,
          const Bnd_Box2d& aBox,
          const Standard_Real aTol)
 {
-  myDetectedIndex = -1;
   Standard_Real Umin,Vmin,Umax,Vmax;
   aBox.Get(Umin,Vmin,Umax,Vmax);
   CSLib_Class2d aClassifier2d(aPoly,aTol,aTol,Umin,Vmin,Umax,Vmax);
@@ -401,21 +414,23 @@ void Select3D_SensitiveCircle::Dump(Standard_OStream& S,const Standard_Boolean F
 //purpose  :
 //=======================================================================
 
-Standard_Real Select3D_SensitiveCircle::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Real Select3D_SensitiveCircle::ComputeDepth (const gp_Lin& thePickLine,
+                                                      const Standard_Integer theDetectedIndex) const
 {
   gp_XYZ aCDG;
-  if(myDetectedIndex==-1)
+  if (theDetectedIndex == -1)
   {
     aCDG = myCenter3D;
   }
   else
   {
-    aCDG += mypolyg.Pnt(myDetectedIndex);
-    aCDG += mypolyg.Pnt(myDetectedIndex+1);
-    aCDG += mypolyg.Pnt(myDetectedIndex+2);
+    aCDG += mypolyg.Pnt (theDetectedIndex);
+    aCDG += mypolyg.Pnt (theDetectedIndex + 1);
+    aCDG += mypolyg.Pnt (theDetectedIndex + 2);
     aCDG /= 3.;
   }
-  return ElCLib::Parameter(EyeLine,gp_Pnt(aCDG));
+
+  return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
 }
 
 //=======================================================================
index 0895a03..b8f0aeb 100755 (executable)
@@ -36,6 +36,7 @@ uses
     Lin             from gp,
     EntityOwner     from SelectBasics,
     ListOfBox2d     from SelectBasics,
+    PickArgs        from SelectBasics,
     Curve           from Geom,
     Array1OfPnt     from TColgp,
     Array1OfPnt2d   from TColgp,
@@ -72,13 +73,15 @@ is
         ---Level: Public 
         ---Purpose: Creation of Sensitive Curve from Points.
         --          Warning : This Method should disappear in the next version...
-  
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is  redefined static;
+
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -95,9 +98,15 @@ is
         ---Level: Public 
     
 
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static; 
-     
+    ComputeDepth (me;
+                  thePickLine : Lin from gp;
+                  theDetectedIndex : Integer from Standard)
+    returns Real from Standard;
+    ---Level: Public
+    ---Purpose: Compute depth of sensitive circle for the detected sub-part.
+    -- @param thePickLine [in] the picking line.
+    -- @param theDetectedIndex [in] index of the detected sub-part.
+    -- @return depth on the picking line.
  
     GetLastDetected(me) returns Integer from Standard;
     ---Purpose: Gets index of last detected segment 
index 5965a33..a873964 100755 (executable)
@@ -76,25 +76,27 @@ mylastseg(0)
 // Purpose :
 //==================================================
 
-Standard_Boolean Select3D_SensitiveCurve
-::Matches(const Standard_Real X,
-          const Standard_Real Y,
-          const Standard_Real aTol,
-          Standard_Real& DMin)
+Standard_Boolean Select3D_SensitiveCurve::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                   Standard_Real& theMatchDMin,
+                                                   Standard_Real& theMatchDepth)
 {
   Standard_Integer Rank;
   TColgp_Array1OfPnt2d aArrayOf2dPnt(1, mypolyg.Size());
   Points2D(aArrayOf2dPnt);
   if (SelectBasics_BasicTool::MatchPolyg2d (aArrayOf2dPnt,
-                                            X, Y,
-                                            aTol,
-                                            DMin,
+                                            thePickArgs.X(), thePickArgs.Y(),
+                                            thePickArgs.Tolerance(),
+                                            theMatchDMin,
                                             Rank))
   {
+    // remember detected segment (for GetLastDetected)
     mylastseg = Rank;
-    // compute and validate the depth (::Depth()) along the eyeline
-    return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
+
+    theMatchDepth = ComputeDepth (thePickArgs.PickLine(), Rank);
+
+    return !thePickArgs.IsClipped (theMatchDepth);
   }
+
   return Standard_False;
 }
 
@@ -189,29 +191,30 @@ void Select3D_SensitiveCurve::Dump(Standard_OStream& S,const Standard_Boolean Fu
 //purpose  :
 //=======================================================================
 
-Standard_Real Select3D_SensitiveCurve::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Real Select3D_SensitiveCurve::ComputeDepth (const gp_Lin& thePickLine,
+                                                     const Standard_Integer theSegment) const
 {
-  Standard_Real aDepth = Precision::Infinite();
-
-  // Not implemented
-  if(mylastseg==0)
-    return aDepth;
+  if (theSegment == 0)
+  {
+    return Precision::Infinite();
+  }
 
-  gp_XYZ aCDG;
-  // In case if mylastseg and mylastseg+1 are not valid
+  // In case if theSegment and theSegment + 1 are not valid
   // the depth will be infinite
-  if (mylastseg < mypolyg.Size())
+  if (theSegment >= mypolyg.Size())
   {
-    aCDG = mypolyg.Pnt(mylastseg);
-    if (mylastseg+1 < mypolyg.Size())
-    {
-      aCDG += mypolyg.Pnt(mylastseg+1);
-      aCDG /= 2.;
-    }
-    aDepth = ElCLib::Parameter(EyeLine,gp_Pnt(aCDG));
+    return Precision::Infinite();
+  }
+
+  gp_XYZ aCDG = mypolyg.Pnt (theSegment);
+
+  if (theSegment + 1 < mypolyg.Size())
+  {
+    aCDG += mypolyg.Pnt(theSegment + 1);
+    aCDG /= 2.;
   }
 
-  return aDepth;
+  return ElCLib::Parameter (thePickLine, gp_Pnt (aCDG));
 }
 
 //=======================================================================
index 92c7a18..b7bd33c 100755 (executable)
@@ -59,14 +59,12 @@ is
     Is3D(me) returns Boolean from Standard is redefined static;
     ---Purpose: Returns true if this framework provides 3D information.
 
-    Project (me:mutable;aProjector : Projector from Select3D) is virtual;
+    Project (me:mutable;aProjector : Projector from Select3D) is deferred;
     ---Level: Public
-       ---Purpose:Returns the projector aProjector.
-       --       In classes inheriting this framework, you must
-       -- redefine this function in order to get a sensitive 2D
-       -- rectangle from a 3D entity. This rectangle is the
-       -- sensitive zone which makes the 3D entity selectable.
-
+    ---Purpose: In classes inheriting this framework, you must
+    -- redefine this function in order to get a sensitive 2D
+    -- rectangle from a 3D entity. This rectangle is the
+    -- sensitive zone which makes the 3D entity selectable.
 
     MaxBoxes(me) returns Integer is redefined virtual;
     ---Level: Public
@@ -87,16 +85,6 @@ is
     -- sensitive entity which can accept another connected
     -- sensitive entity.//can be connected to another sensitive entity.
 
-    Matches(me  :mutable;
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard)
-    returns Boolean is redefined virtual;
-    ---Purpose: Matches the coordinates X, Y with the entity found at
-    -- that point within the tolerance aTol and the minimum depth DMin.
-    -- You must redefine this function for every inheriting entity.
-    -- You will have to call this framework inside the redefined function.
-
     Matches (me  :mutable;
              XMin,YMin,XMax,YMax : Real from Standard;
              aTol: Real from Standard)
@@ -117,23 +105,6 @@ is
     returns Boolean from Standard is redefined virtual;
     ---Purpose: prevents from hiding virtual methods...
 
-
-    GetEyeLine(me; X,Y : Real from Standard) returns Lin from gp;
-    ---Purpose: Returns the eye line for the point defined by the coordinates X,Y.
-
-    ComputeDepth(me;EyeLine : Lin from gp) returns Real from Standard
-    is deferred;
-    ---Purpose: Returns the depth of this object on the line EyeLine.
-    -- EyeLine goes through the eye towards a point
-    -- defined by the coordinates X,Y in the function GetEyeLine.
-    ---Purpose: gives an abcissa on <aLin> .
-    --          <aLin> represents the line going through
-    --          the eye towards an X,Y point on the screen. This Method
-    --          must return a mean Depth on this line.
-
-
-    Depth(me) returns Real from Standard is redefined;
-
     ---Category: Location of sensitive entities...
     --           Default implementations of HasLocation() and Location() rely on
     --           location obtained from the entity owner, to minimize memory usage.
@@ -159,15 +130,6 @@ is
 
     UpdateLocation(me:mutable;aLoc:Location from TopLoc);
 
-
-    SetLastPrj(me:mutable;aPrj:Projector from Select3D) is virtual;
-
-    SetLastDepth(me:mutable; aDepth: Real from Standard) is protected;
-
-fields
-
-    mylastprj     : Projector from Select3D  is protected;
-    mylastdepth   : ShortReal from Standard;
 end SensitiveEntity;
 
 
index 145671c..6e45909 100755 (executable)
 //=======================================================================
 
 Select3D_SensitiveEntity::Select3D_SensitiveEntity(const Handle(SelectBasics_EntityOwner)& OwnerId):
-SelectBasics_SensitiveEntity(OwnerId),
-mylastprj(),
-mylastdepth(ShortRealLast())
+SelectBasics_SensitiveEntity(OwnerId)
 {}
 
 //=======================================================================
-//function : Project
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::Project(const Handle(Select3D_Projector)& aPrj)
-{
-  mylastprj = aPrj;
-}
-
-//=======================================================================
-//function : Matches
-//purpose  : 
-//=======================================================================
-
-Standard_Boolean Select3D_SensitiveEntity::Matches(const Standard_Real X,
-                                                   const Standard_Real Y,
-                                                   const Standard_Real /*aTol*/,
-                                                   Standard_Real&  /*DMin*/)
-{
-  if (!mylastprj.IsNull())
-  {
-    gp_Lin L = mylastprj->Shoot (X, Y);
-    SetLastDepth (ComputeDepth (L));
-    return (mylastdepth > mylastprj->DepthMin()) && (mylastdepth < mylastprj->DepthMax());
-  }
-  else
-  {
-    SetLastDepth (ComputeDepth (gp_Lin())); // how we determine depth without eyeline here?
-    return (mylastdepth > ShortRealFirst()) && (mylastdepth < ShortRealLast());
-  }
-}
-
-//=======================================================================
 //function : Matches
 //purpose  : 
 //=======================================================================
@@ -190,30 +155,6 @@ Standard_Boolean Select3D_SensitiveEntity::Is3D() const
 {return Standard_True;}
 
 //=======================================================================
-//function : Depth
-//purpose  : 
-//=======================================================================
-
-Standard_Real Select3D_SensitiveEntity::Depth() const
-{return mylastdepth;}
-
-//=======================================================================
-//function : GetEyeLine
-//purpose  : 
-//=======================================================================
-
-gp_Lin Select3D_SensitiveEntity::GetEyeLine(const Standard_Real X,
-                                            const Standard_Real Y) const
-{
-  gp_Lin L;
-  if (!mylastprj.IsNull())
-  {
-    L = mylastprj->Shoot (X, Y);
-  }
-  return L;
-}
-
-//=======================================================================
 //function : MaxBoxes
 //purpose  : 
 //=======================================================================
@@ -222,15 +163,6 @@ Standard_Integer Select3D_SensitiveEntity::MaxBoxes() const
 {return 1;}
 
 //=======================================================================
-//function : SetLastPrj
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveEntity::SetLastPrj(const Handle(Select3D_Projector)& aprj)
-{ mylastprj = aprj; }
-
-
-//=======================================================================
 //function : GetConnected
 //purpose  : 
 //=======================================================================
@@ -240,12 +172,3 @@ Handle(Select3D_SensitiveEntity) Select3D_SensitiveEntity::GetConnected(const To
   Handle(Select3D_SensitiveEntity) NiouEnt;
   return NiouEnt;
 }
-
-//=======================================================================
-//function : SetLastDepth
-//purpose  : 
-//=======================================================================
-void Select3D_SensitiveEntity::SetLastDepth(const Standard_Real aDepth)
-{
-  mylastdepth = DToF(aDepth);
-}
index 1d783d5..cc53659 100755 (executable)
@@ -32,6 +32,7 @@ uses
     Projector         from Select3D,
     Lin               from gp,
     ListOfBox2d       from SelectBasics,
+    PickArgs          from SelectBasics,
     Array1OfPnt       from TColgp,
     HArray1OfPnt      from TColgp,
     Array1OfPnt2d     from TColgp,
@@ -66,12 +67,14 @@ is
         -- the sensitivity type Sensitivity.
         -- The array of points is the outer polygon of the geometric face.
    
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is redefined virtual;
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined virtual;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -89,14 +92,22 @@ is
     ---Level: Public 
     
 
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined virtual;
+    ComputeDepth (me;
+                  thePickLine : Lin from gp;
+                  theDepthMin, theDepthMax : Real from Standard)
+    returns Real from Standard
+    is virtual;
     ---Level: Public
     ---Purpose: Computes the depth values for all 3D points defining this face and returns
-    -- the minimal value among them. 
+    -- the minimal value among them.
     -- If the "minimal depth" approach is not suitable and gives wrong detection results
-    -- in some particular case, a custom sensitive face class can be implemented at application level
-    -- that overrides default ComputeDepth() behavior.
+    -- in some particular case, a custom sensitive face class can redefine this method.
+
+    ComputeDepth(me;EyeLine: Lin from gp)
+    is private;
+    ---Level: Public
+    ---Purpose: Warning: Obsolete.
+    -- Use newer version of the method with min, max limits passed as arguments.
 
     Dump(me; S: in out OStream;FullDump : Boolean from Standard = Standard_True) is redefined virtual; 
 
@@ -110,6 +121,4 @@ is
 fields
 
     mytype          : TypeOfSensitivity;
-    myautointer     : Boolean;
-
 end SensitiveFace;
index 524c40f..d45cde8 100755 (executable)
 
 #include <CSLib_Class2d.hxx>
 
-
-#define AutoInterMask  0x01
-#define AutoComputeMask  0x02
-// Standard_True if the flag is one
-#define AutoInterFlag(aflag)  ( aflag & AutoInterMask )
-#define AutoComputeFlag(aflag)  ( aflag & AutoComputeMask )
-// set the flag to one
-#define SetAutoInterFlag(aflag)  ( aflag = aflag & AutoInterMask)
-#define SetAutoComputeFlag(aflag)  ( aflag = aflag & AutoComputeMask)
-// Initialize flags
-#define AutoInitFlags(aflag) (aflag = 0)
-
 //==================================================
 // Function: Hide this constructor to the next version...
 // Purpose : simply avoid interfering with the version update
@@ -56,7 +44,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
 Select3D_SensitivePoly(OwnerId, ThePoints),
 mytype (aType)
 {
-  AutoInitFlags(myautointer);
 }
 
 //==================================================
@@ -71,7 +58,6 @@ Select3D_SensitiveFace(const Handle(SelectBasics_EntityOwner)& OwnerId,
 Select3D_SensitivePoly(OwnerId, ThePoints),
 mytype (aType)
 {
-  AutoInitFlags(myautointer);
 }
 
 //==================================================
@@ -79,11 +65,9 @@ mytype (aType)
 // Purpose :
 //==================================================
 
-Standard_Boolean Select3D_SensitiveFace::
-Matches(const Standard_Real X,
-        const Standard_Real Y,
-        const Standard_Real aTol,
-        Standard_Real& DMin)
+Standard_Boolean Select3D_SensitiveFace::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                  Standard_Real& theMatchDMin,
+                                                  Standard_Real& theMatchDepth)
 {
   Standard_Real DMin2 = 0.;
   Standard_Real Xmin = 0.,Ymin = 0.,Xmax = 0.,Ymax = 0.;
@@ -96,7 +80,7 @@ Matches(const Standard_Real X,
   // from start Dmin = size of the bounding box 2D,
   // then min. distance of the polyhedron or cdg...
 
-  Standard_Real aTol2 = aTol*aTol;
+  Standard_Real aTol2 = thePickArgs.Tolerance() * thePickArgs.Tolerance();
   Standard_Integer aSize = mypolyg.Size(), anIndex;
   gp_XY CDG;
   for(anIndex=0;anIndex<aSize;++anIndex)
@@ -108,14 +92,14 @@ Matches(const Standard_Real X,
   {
     CDG/=(aSize-1);
   }
-  DMin2=Min(DMin2,gp_XY(CDG.X()-X,CDG.Y()-Y).SquareModulus());
-  DMin = Sqrt(DMin2);
+  DMin2 = Min (DMin2, gp_XY (CDG.X() - thePickArgs.X(), CDG.Y() - thePickArgs.Y()).SquareModulus());
+  theMatchDMin = Sqrt(DMin2);
 
   Standard_Boolean isplane2d(Standard_True);
 
   for(anIndex=1;anIndex<aSize;++anIndex)
   {
-    gp_XY V1(mypolyg.Pnt2d(anIndex)),V(X,Y);
+    gp_XY V1(mypolyg.Pnt2d(anIndex)),V(thePickArgs.X(), thePickArgs.Y());
     V1-=mypolyg.Pnt2d(anIndex-1);
     V-=mypolyg.Pnt2d(anIndex-1);
     Standard_Real Vector = V1^V;
@@ -128,18 +112,25 @@ Matches(const Standard_Real X,
     gp_XY PlaneTest(CDG);
     PlaneTest-=mypolyg.Pnt2d(anIndex-1);
     Standard_Real valtst = PlaneTest^V1;
-    if(isplane2d && Abs(valtst)>aTol) isplane2d=Standard_False;
+    if(isplane2d && Abs(valtst) > thePickArgs.Tolerance()) isplane2d=Standard_False;
   }
   if (isplane2d)
   {
-    return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+    theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
+                                  thePickArgs.DepthMin(),
+                                  thePickArgs.DepthMax());
+
+    return !thePickArgs.IsClipped (theMatchDepth);
   }
 
   //otherwise it is checked if the point is in the face...
   TColgp_Array1OfPnt2d aArrayOf2dPnt(1, aSize);
   Points2D(aArrayOf2dPnt);
-  CSLib_Class2d TheInOutTool(aArrayOf2dPnt,aTol,aTol,Xmin,Ymin,Xmax,Ymax);
-  Standard_Integer TheStat = TheInOutTool.SiDans(gp_Pnt2d(X,Y));
+  CSLib_Class2d TheInOutTool (aArrayOf2dPnt,
+                              thePickArgs.Tolerance(),
+                              thePickArgs.Tolerance(),
+                              Xmin, Ymin, Xmax, Ymax);
+  Standard_Integer TheStat = TheInOutTool.SiDans (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()));
 
   Standard_Boolean res(Standard_False);
   switch(TheStat)
@@ -154,7 +145,11 @@ Matches(const Standard_Real X,
   }
   if (res)
   {
-    return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+    theMatchDepth = ComputeDepth (thePickArgs.PickLine(),
+                                  thePickArgs.DepthMin(),
+                                  thePickArgs.DepthMax());
+
+    return !thePickArgs.IsClipped (theMatchDepth);
   }
   return Standard_False;
 }
@@ -232,26 +227,35 @@ void Select3D_SensitiveFace::Dump(Standard_OStream& S,const Standard_Boolean Ful
 //purpose  :
 //=======================================================================
 
-Standard_Real Select3D_SensitiveFace::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Real Select3D_SensitiveFace::ComputeDepth (const gp_Lin& thePickLine,
+                                                    const Standard_Real theDepthMin,
+                                                    const Standard_Real theDepthMax) const
 {
   Standard_Real aDepth = Precision::Infinite();
-
-  Standard_Real aDepthMin = !mylastprj.IsNull() ? mylastprj->DepthMin() : -Precision::Infinite();
-  Standard_Real aDepthMax = !mylastprj.IsNull() ? mylastprj->DepthMax() :  Precision::Infinite();
-  Standard_Real aDepthTest;
+  Standard_Real aPointDepth;
 
   for (Standard_Integer anIndex = 0; anIndex < mypolyg.Size()-1; ++anIndex)
   {
-    aDepthTest = ElCLib::Parameter (EyeLine, mypolyg.Pnt(anIndex));
-    if (aDepthTest < aDepth && (aDepthTest > aDepthMin) && (aDepthTest < aDepthMax))
+    aPointDepth = ElCLib::Parameter (thePickLine, mypolyg.Pnt(anIndex));
+    if (aPointDepth < aDepth && (aPointDepth > theDepthMin) && (aPointDepth < theDepthMax))
     {
-      aDepth = aDepthTest;
+      aDepth = aPointDepth;
     }
   }
   return aDepth;
 }
 
 //=======================================================================
+//function : ComputeDepth
+//purpose  :
+//=======================================================================
+
+void Select3D_SensitiveFace::ComputeDepth(const gp_Lin& /*theEyeLine*/) const
+{
+  // this method is obsolete.
+}
+
+//=======================================================================
 //function : GetConnected
 //purpose  :
 //=======================================================================
index 78689a7..bbe7a88 100755 (executable)
@@ -38,6 +38,7 @@ uses
     SensitiveEntity          from Select3D,
     ListOfSensitive          from Select3D,
     ListOfBox2d              from SelectBasics,
+    PickArgs                 from SelectBasics,
     Array1OfPnt2d            from TColgp,
     Box2d                    from Bnd,
     Location                 from TopLoc
@@ -115,15 +116,14 @@ is
     ResetLocation(me:mutable) is redefined static;
        ---Purpose:  propagation of location on all the sensitive inside...    
 
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is  redefined static;
-       ---Level: Public 
-       ---Purpose: projection of the sensitive primitive in order to
-       --          get 2D boxes for the Sort Algorithm
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -138,14 +138,6 @@ is
     returns Boolean
     is redefined virtual;
        ---Level: Public 
-    
-
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
-       ---Purpose: returns the depth of the touched entity
-
-    
-    SetLastPrj(me:mutable;aPrj:Projector from Select3D) is redefined virtual;
 
     Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; 
     ---Purpose: Sets the owner for all entities in group 
@@ -160,8 +152,5 @@ is
 fields
     myList         : ListOfSensitive from Select3D;
     myMustMatchAll : Boolean from Standard;
-    myLastRank     : Integer from Standard;
-    myLastTol      : ShortReal from Standard;
-    myX,myY       : ShortReal from Standard;
 end SensitiveGroup;
 
index 554afff..62792e8 100755 (executable)
 Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_EntityOwner)& OwnerId,
                                                  const Standard_Boolean MatchAll):
 Select3D_SensitiveEntity(OwnerId),
-myMustMatchAll(MatchAll),
-myLastRank(0),
-myX(0.),
-myY(0.)
+myMustMatchAll(MatchAll)
 {
 }
 
@@ -47,10 +44,7 @@ Select3D_SensitiveGroup::Select3D_SensitiveGroup(const Handle(SelectBasics_Entit
                                                  Select3D_ListOfSensitive& TheList, 
                                                  const Standard_Boolean MatchAll):
 Select3D_SensitiveEntity(OwnerId),
-myMustMatchAll(MatchAll),
-myLastRank(0),
-myX(0.),
-myY(0.)
+myMustMatchAll(MatchAll)
 {
   myList.Append(TheList);
 }
@@ -124,8 +118,6 @@ void Select3D_SensitiveGroup::Clear()
 
 void Select3D_SensitiveGroup::Project(const Handle(Select3D_Projector)& aProjector) 
 {
-  Select3D_SensitiveEntity::Project(aProjector); // to set the field last proj...
-
   for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()) 
   {
     It.Value()->Project(aProjector);
@@ -215,28 +207,34 @@ void Select3D_SensitiveGroup::ResetLocation()
 //purpose  : 
 //=======================================================================
 
-Standard_Boolean Select3D_SensitiveGroup::Matches(const Standard_Real X, 
-                                                  const Standard_Real Y, 
-                                                  const Standard_Real aTol, 
-                                                  Standard_Real& DMin) 
+Standard_Boolean Select3D_SensitiveGroup::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                   Standard_Real& theMatchDMin,
+                                                   Standard_Real& theMatchDepth)
 {
-  myLastRank = 0;
-  myLastTol = (Standard_ShortReal)aTol;
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next()){
-    myLastRank++;
-    if (It.Value()->Matches (X, Y, aTol, DMin))
+  theMatchDMin = RealLast();
+  theMatchDepth = RealLast();
+  Standard_Real aChildDMin, aChildDepth;
+  Standard_Boolean isMatched = Standard_False;
+
+  Select3D_ListIteratorOfListOfSensitive anIt (myList);
+  for (; anIt.More(); anIt.Next())
+  {
+    Handle(SelectBasics_SensitiveEntity)& aChild = anIt.Value();
+    if (!aChild->Matches (thePickArgs, aChildDMin, aChildDepth))
+    {
+      continue;
+    }
+
+    if (!isMatched)
     {
-      myX = (Standard_ShortReal)X;
-      myY = (Standard_ShortReal)Y;
-      myLastTol = (Standard_ShortReal)aTol;
-      // compute and validate the depth (will call ::ComputeDepth())
-      return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin);
+      theMatchDMin = aChildDMin;
+      isMatched = Standard_True;
     }
+
+    theMatchDepth = Min (aChildDepth, theMatchDepth);
   }
-  // no match
-  myLastRank = 0;
-  SetLastDepth (ShortRealLast());
-  return Standard_False;
+
+  return isMatched;
 }
 
 //=======================================================================
@@ -302,37 +300,6 @@ Matches (const TColgp_Array1OfPnt2d& aPoly,
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  : to optimise, the minimum depth for 
-//          entities that answer YES to Matches(X,Y,...) is taken
-//          the test is started from mylastRank...
-//=======================================================================
-Standard_Real Select3D_SensitiveGroup::ComputeDepth(const gp_Lin& EyeLine) const
-{
-  Standard_Integer currank = 0;
-  Standard_Real DMin, thedepth (Precision::Infinite());
-  for (Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
-  {
-    currank++;
-    if (currank >= myLastRank)
-    {
-      // this recomputes and validates the depth for the entity
-      if (It.Value()->Matches (myX, myY, myLastTol, DMin))
-      {
-        It.Value()->ComputeDepth (EyeLine);
-        if (It.Value()->Depth() < thedepth)
-        {
-          // search for topmost entity
-          thedepth = It.Value()->Depth();
-          //myLastRank = currank; // can not do this here...
-        }
-      }
-    }
-  }
-  return thedepth;
-}
-
-//=======================================================================
 //function : MaxBoxes
 //purpose  : 
 //=======================================================================
@@ -347,18 +314,6 @@ Standard_Integer Select3D_SensitiveGroup::MaxBoxes() const
 }
 
 //=======================================================================
-//function : SetLastPrj
-//purpose  : 
-//=======================================================================
-
-void Select3D_SensitiveGroup::SetLastPrj(const Handle(Select3D_Projector)& Prj)
-{
-  Select3D_SensitiveEntity::SetLastPrj(Prj);
-  for(Select3D_ListIteratorOfListOfSensitive It(myList);It.More();It.Next())
-    It.Value()->SetLastPrj(Prj);
-}
-
-//=======================================================================
 //function : Set
 //purpose  : 
 //=======================================================================
index 33c7bcd..2847481 100755 (executable)
@@ -32,6 +32,7 @@ uses
     Lin             from gp,
     EntityOwner     from SelectBasics,
     ListOfBox2d     from SelectBasics,
+    PickArgs        from SelectBasics,
     Location        from TopLoc,
     Box2d             from Bnd,
     Array1OfPnt2d     from TColgp, 
@@ -62,16 +63,15 @@ is
 
     GetConnected(me:mutable;aLocation: Location from TopLoc)
     returns SensitiveEntity from Select3D is redefined static;
-    
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is redefined static;    
-    ---Level: Public 
-    ---Purpose: returns true if the X,Y position matches the point
-    --          else gives the distance between them.
+
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -90,7 +90,7 @@ is
     
 
     ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
+    returns Real from Standard;
 
       
     Point(me) returns Pnt from gp;
index ae5d5c3..7b600ee 100755 (executable)
@@ -50,7 +50,6 @@ Select3D_SensitiveEntity(anOwner)
 void Select3D_SensitivePoint
 ::Project (const Handle(Select3D_Projector)& aProj)
 {
-  Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
   gp_Pnt2d aPoint2d;
   if(!HasLocation())
     aProj->Project(mypoint, aPoint2d);
@@ -80,19 +79,26 @@ void Select3D_SensitivePoint
 // Purpose :
 //==================================================
 
-Standard_Boolean Select3D_SensitivePoint
-::Matches(const Standard_Real X,
-          const Standard_Real Y,
-          const Standard_Real aTol,
-          Standard_Real& DMin)
+Standard_Boolean Select3D_SensitivePoint::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                   Standard_Real& theMatchDMin,
+                                                   Standard_Real& theMatchDepth)
 {
-  DMin = gp_Pnt2d(X,Y).Distance(myprojpt);
-  if(DMin<=aTol*SensitivityFactor())
+  // check coordinate matching
+  Standard_Real aDist = gp_Pnt2d (thePickArgs.X(), thePickArgs.Y()).Distance (myprojpt);
+  if (aDist > thePickArgs.Tolerance() * SensitivityFactor())
   {
-    // compute and validate the depth (::Depth()) along the eyeline
-    return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+    return Standard_False;
   }
-  return Standard_False;
+
+  Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
+  if (thePickArgs.IsClipped (aDepth))
+  {
+    return Standard_False;
+  }
+
+  theMatchDMin = aDist;
+  theMatchDepth = aDepth;
+  return Standard_True;
 }
 
 //==================================================
index 4c440e4..ffbfc6e 100755 (executable)
@@ -74,7 +74,6 @@ mypolyg(NbPoints)
 
 void Select3D_SensitivePoly::Project(const Handle(Select3D_Projector)& aProj)
 {
-  Select3D_SensitiveEntity:: Project (aProj); // to set the field last proj...
   mybox2d.SetVoid();
 
   Standard_Boolean hasloc = HasLocation();
index 34b1948..ec8af00 100755 (executable)
@@ -38,6 +38,7 @@ uses
     Lin              from gp,
     EntityOwner      from SelectBasics,
     ListOfBox2d      from SelectBasics,
+    PickArgs         from SelectBasics,
     Array1OfPnt2d    from TColgp,
     Box2d            from Bnd,
     Location         from TopLoc,
@@ -112,16 +113,15 @@ is
 
     GetConnected(me:mutable;aLocation: Location from TopLoc)
     returns SensitiveEntity from Select3D is redefined static;
-    
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is  redefined static;
-       ---Level: Public 
-       ---Purpose: projection of the sensitive primitive in order to
-       --          get 2D boxes for the Sort Algorithm
+
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -139,7 +139,7 @@ is
     
         
     ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
+    returns Real from Standard;
 
     MaxBoxes(me) returns Integer is redefined static;    
        ---Level: Public 
index d176dbe..1476afc 100755 (executable)
@@ -62,7 +62,6 @@ mymaxrect(MaxRect)
 void Select3D_SensitiveSegment
 ::Project(const Handle(Select3D_Projector)& aProj)
 {
-  Select3D_SensitiveEntity::Project(aProj); // to set the field last proj...
   gp_Pnt2d aPoint2dStart;
   gp_Pnt2d aPoint2dEnd;
 
@@ -137,17 +136,24 @@ void Select3D_SensitiveSegment
 // Purpose  :
 //=====================================================
 
-Standard_Boolean Select3D_SensitiveSegment
-::Matches(const Standard_Real X,
-          const Standard_Real Y,
-          const Standard_Real aTol,
-          Standard_Real&  DMin)
+Standard_Boolean Select3D_SensitiveSegment::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                     Standard_Real& theMatchDMin,
+                                                     Standard_Real& theMatchDepth)
 {
-  gp_Pnt2d aPStart(myprojstart.x,myprojstart.y);
-  gp_Pnt2d aPEnd(myprojend.x,myprojend.y);
-  if ( ! SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd, X, Y, aTol, DMin) )
+  gp_Pnt2d aPStart (myprojstart.x,myprojstart.y);
+  gp_Pnt2d aPEnd (myprojend.x,myprojend.y);
+  if (!SelectBasics_BasicTool::MatchSegment (aPStart, aPEnd,
+                                             thePickArgs.X(),
+                                             thePickArgs.Y(),
+                                             thePickArgs.Tolerance(),
+                                             theMatchDMin))
+  {
     return Standard_False;
-  return Select3D_SensitiveEntity::Matches (X, Y, aTol, DMin); // compute and validate depth
+  }
+
+  theMatchDepth = ComputeDepth (thePickArgs.PickLine());
+
+  return !thePickArgs.IsClipped (theMatchDepth);
 }
 
 //=====================================================
index 40f940c..859b8f4 100755 (executable)
@@ -33,6 +33,7 @@ uses
     Projector        from Select3D,
     Lin              from gp,
     ListOfBox2d      from SelectBasics,
+    PickArgs         from SelectBasics,
     Array1OfPnt2d    from TColgp,
     Box2d            from Bnd,
     XY               from gp,
@@ -54,12 +55,14 @@ is
         ---Purpose: Constructs a sensitive triangle object defined by the
         -- owner OwnerId, the points P1, P2, P3, and the type of sensitivity Sensitivity. 
 
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
-    returns Boolean
-    is redefined virtual;
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
+    returns Boolean is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -78,7 +81,7 @@ is
     
     
     ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
+    returns Real from Standard;
 
 
     Points3D(me; P1,P2,P3 : out Pnt from gp) ;
index b073b5c..022d174 100755 (executable)
@@ -79,28 +79,37 @@ mytype (aType)
 // Purpose :
 //==================================================
 
-Standard_Boolean Select3D_SensitiveTriangle::
-Matches(const Standard_Real X,
-        const Standard_Real Y,
-        const Standard_Real aTol,
-        Standard_Real& DMin)
+Standard_Boolean Select3D_SensitiveTriangle::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                      Standard_Real& theMatchDMin,
+                                                      Standard_Real& theMatchDepth)
 {
-  Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-  if(Bnd_Box2d(mybox2d).IsOut(gp_Pnt2d(X,Y))) return Standard_False;
+  Standard_Real aDepth = ComputeDepth (thePickArgs.PickLine());
+  if (thePickArgs.IsClipped (aDepth))
+  {
+    return Standard_False;
+  }
+
+  theMatchDepth = aDepth;
+
+  if (Bnd_Box2d (mybox2d).IsOut (gp_Pnt2d (thePickArgs.X(), thePickArgs.Y())))
+  {
+    return Standard_False;
+  }
 
   Standard_Integer Res;
   switch (mytype)
   {
   case Select3D_TOS_BOUNDARY:
-    Res = Status(X,Y,aTol,DMin);
+    Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
     return Res== 1;
     break;
   case Select3D_TOS_INTERIOR:
-    Res = Status(X,Y,aTol,DMin);
+    Res = Status (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin);
     return (Res==0 || Res == 1);
   default:
     break;
   }
+
   return Standard_True;
 }
 
index b53e2c2..fcc7c60 100755 (executable)
@@ -31,6 +31,7 @@ uses
     Lin              from gp,
     Trsf             from gp,
     ListOfBox2d      from SelectBasics,
+    PickArgs         from SelectBasics,
     Array1OfPnt      from TColgp,
     Array1OfPnt2d    from TColgp,
     HArray1OfInteger from TColStd,
@@ -83,12 +84,15 @@ is
     GetConnected(me:mutable;aLocation: Location from TopLoc)
     returns SensitiveEntity from Select3D is redefined static;
 
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
     returns Boolean
     is redefined virtual;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -104,12 +108,16 @@ is
     returns Boolean
     is redefined virtual;
        ---Level: Public 
-    
-    
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
-       ---Purpose: give the depht of the last detected triangle
-       --          (center of gravity)
+
+    ComputeDepth (me;
+                  thePickLine : Lin from gp;
+                  theTriangle : Integer from Standard)
+    returns Real from Standard;
+    ---Level: Public
+    ---Purpose: Compute precise depth of detected triangle.
+    -- @param thePickLine [in] the picking line.
+    -- @param theTriangle [in] the index of detected triangle.
+    -- @return depth on the picking line.
 
     DetectedTriangle(me) returns Integer from Standard;
        ---Purpose: Returns the detected three nodes P1, P2, P3 constituting a triangle.
index 84871f2..5263884 100755 (executable)
@@ -207,8 +207,6 @@ myDetectedTr(-1)
 
 void Select3D_SensitiveTriangulation::Project(const Handle(Select3D_Projector)& aPrj)
 {
-  Select3D_SensitiveEntity::Project(aPrj); // to set the field last proj...
-
   mybox2d.SetVoid();
   const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
 
@@ -241,27 +239,25 @@ void Select3D_SensitiveTriangulation::Areas(SelectBasics_ListOfBox2d& boxes)
 //function : Matches
 //purpose  :
 //=======================================================================
-Standard_Boolean Select3D_SensitiveTriangulation::
-Matches(const Standard_Real X,
-        const Standard_Real Y,
-        const Standard_Real aTol,
-        Standard_Real& DMin)
-{
-  // get view direction (necessary for calculation of depth) from field mylastprj of the base class
-  if (mylastprj.IsNull())
-    return Standard_False;
 
-  DMin = Precision::Infinite();
-  gp_XY BidPoint(X,Y);
+Standard_Boolean Select3D_SensitiveTriangulation::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                           Standard_Real& theMatchDMin,
+                                                           Standard_Real& theMatchDepth)
+{
+  theMatchDMin = Precision::Infinite();
+  gp_XY BidPoint (thePickArgs.X(), thePickArgs.Y());
   myDetectedTr = -1;
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
 
   // it is checked if we are inside the triangle 2d.
   if(myIntFlag)
   {
-    gp_Lin EyeLine = mylastprj->Shoot(X,Y);
-    if ( myTrsf.Form()!=gp_Identity )
-      EyeLine.Transform (myTrsf.Inverted());
+    gp_Lin aPickingLine = thePickArgs.PickLine();
+
+    if (myTrsf.Form() != gp_Identity)
+    {
+      aPickingLine.Transform (myTrsf.Inverted());
+    }
 
     Standard_Real aMinDepth = Precision::Infinite();
     const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
@@ -274,24 +270,22 @@ Matches(const Standard_Real X,
       const gp_XY& aPnt2d3 = myNodes2d(n3).XY();
       gp_XY aUV;
       Standard_Real aDistSquare = Poly::PointOnTriangle (aPnt2d1, aPnt2d2, aPnt2d3, BidPoint, aUV);
-      if ( aDistSquare > aTol * aTol )
+      if (aDistSquare > thePickArgs.Tolerance() * thePickArgs.Tolerance())
         continue;
 
-      // compute depth on this triangle
-      Standard_Real aDepth1 = ElCLib::Parameter (EyeLine, Nodes(n1));
-      Standard_Real aDepth2 = ElCLib::Parameter (EyeLine, Nodes(n2));
-      Standard_Real aDepth3 = ElCLib::Parameter (EyeLine, Nodes(n3));
+      // get interpolated depth of the triangle nodes
+      Standard_Real aDepth1 = ElCLib::Parameter (aPickingLine, Nodes(n1));
+      Standard_Real aDepth2 = ElCLib::Parameter (aPickingLine, Nodes(n2));
+      Standard_Real aDepth3 = ElCLib::Parameter (aPickingLine, Nodes(n3));
       Standard_Real aDepth = aDepth1 + aUV.X() * (aDepth2 - aDepth1) +
                                        aUV.Y() * (aDepth3 - aDepth1);
 
-      // take triangle with lowest depth and within defined depth interval
-      if (aDepth < aMinDepth &&
-          aDepth > mylastprj->DepthMin() &&
-          aDepth < mylastprj->DepthMax())
+      // accept triangle with lowest depth and within defined depth interval
+      if (aDepth < aMinDepth && !thePickArgs.IsClipped(aDepth))
       {
         aMinDepth = aDepth;
         myDetectedTr = itr;
-        DMin = Sqrt (aDistSquare);
+        theMatchDMin = Sqrt (aDistSquare);
       }
     }
   }
@@ -312,7 +306,7 @@ Matches(const Standard_Real X,
       Node2 = FreeE(ifri+1);
       if (S3D_STriangul_NearSegment (myNodes2d(Node1).XY(),
                                      myNodes2d(Node2).XY(),
-                                     BidPoint, aTol, DMin) )
+                                     BidPoint, thePickArgs.Tolerance(), theMatchDMin))
       {
         for(Standard_Integer itr=1; itr <= myTriangul->NbTriangles(); itr++)
         {
@@ -330,10 +324,13 @@ Matches(const Standard_Real X,
   if ( myDetectedTr <= 0 )
     return Standard_False;
 
-  // compute and validate the depth (::Depth()) along the eyeline
-  return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
-}
+  // get precise depth for the detected triangle
+  theMatchDepth = ComputeDepth (thePickArgs.PickLine(), myDetectedTr);
 
+  // this test should not fail if the topmost triangle is taken from the
+  // first if-case block (for other cases this test make sense?)
+  return !thePickArgs.IsClipped (theMatchDepth);
+}
 
 //=======================================================================
 //function : Matches
@@ -509,86 +506,117 @@ void Select3D_SensitiveTriangulation::Dump(Standard_OStream& S,const Standard_Bo
 //purpose  :
 //=======================================================================
 
-Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& EyeLine) const
+Standard_Real Select3D_SensitiveTriangulation::ComputeDepth(const gp_Lin& thePickLine,
+                                                            const Standard_Integer theTriangle) const
 {
-  if(myDetectedTr==-1) return Precision::Infinite(); // currently not implemented...
+  if (theTriangle == -1)
+  {
+    return Precision::Infinite(); // currently not implemented...
+  }
+
   const Poly_Array1OfTriangle& triangles = myTriangul->Triangles();
   const TColgp_Array1OfPnt& Nodes = myTriangul->Nodes();
 
   Standard_Integer n1,n2,n3;
-  triangles(myDetectedTr).Get(n1,n2,n3);
+  triangles (theTriangle).Get (n1,n2,n3);
   gp_Pnt P[3]={Nodes(n1),Nodes(n2),Nodes(n3)};
 
-  if(myTrsf.Form()!=gp_Identity)
+  if (myTrsf.Form() != gp_Identity)
   {
-    for(Standard_Integer i =0;i<=2;i++)
+    for (Standard_Integer i =0; i<=2; i++)
     {
-      P[i].Transform(myTrsf);
+      P[i].Transform (myTrsf);
     }
   }
 
   // formula calculate the parameter of the point on the intersection
   // t = (P1P2 ^P1P3)* OP1  / ((P1P2^P1P3)*Dir)
-  Standard_Real prof(Precision::Infinite());
-  gp_Pnt Oye  = EyeLine.Location(); // origin of the target line eye/point...
-  gp_Dir Dir  = EyeLine.Direction();
+  Standard_Real prof (Precision::Infinite());
+  gp_Pnt Oye  = thePickLine.Location(); // origin of the target line eye/point...
+  gp_Dir Dir  = thePickLine.Direction();
 
   gp_Vec Vtr[3];
-  for(Standard_Integer i=0;i<=2;i++)
-    Vtr[i] = gp_Vec(P[i%3],P[(i+1)%3]);
+  for (Standard_Integer i=0; i<=2; i++)
+  {
+    Vtr[i] = gp_Vec (P[i%3], P[(i+1)%3]);
+  }
+
   Vtr[2] = -Vtr[2];
 
   // remove singular cases immediately...
-  Standard_Integer SingularCase(-1);
-  if(Vtr[0].SquareMagnitude()<= Precision::Confusion())
+  Standard_Integer SingularCase (-1);
+  if (Vtr[0].SquareMagnitude() <= Precision::Confusion())
+  {
     SingularCase = 0;
-  if(Vtr[1].SquareMagnitude()<= Precision::Confusion())
+  }
+
+  if (Vtr[1].SquareMagnitude() <= Precision::Confusion())
+  {
     SingularCase = (SingularCase == -1) ? 1 : 2;
+  }
+
 #ifdef BUC60858
-  if(Vtr[2].SquareMagnitude()<= Precision::Confusion())
+  if (Vtr[2].SquareMagnitude() <= Precision::Confusion())
+  {
     if( SingularCase < 0 ) SingularCase = 1;
+  }
 #endif
 
   // 3 pts mixed...
-  if(SingularCase ==2)
+  if (SingularCase ==2)
   {
-    prof= ElCLib::Parameter(EyeLine,P[0]);
+    prof = ElCLib::Parameter (thePickLine, P[0]);
     return prof;
   }
 
-  if(SingularCase!=0)
+  if (SingularCase!=0)
+  {
     Vtr[0].Normalize();
-  if(SingularCase!=1 &&
-     SingularCase!=2)
+  }
+
+  if (SingularCase!=1 && SingularCase!=2)
+  {
     Vtr[2].Normalize();
-  gp_Vec OPo(Oye,P[0]);
+  }
+
+  gp_Vec OPo (Oye, P[0]);
+
   // 2 points mixed... the intersection between the segment and the target line eye/point.
-  //
-  if(SingularCase!=-1)
+  if (SingularCase!=-1)
   {
     gp_Vec V = SingularCase==0 ? Vtr[2] : Vtr[0];
     gp_Vec Det = Dir^V;
     gp_Vec VSM = OPo^V;
-    if(Det.X()> Precision::Confusion())
-      prof = VSM.X()/Det.X();
-    else if (Det.Y()> Precision::Confusion())
-      prof = VSM.Y()/Det.Y();
-    else if(Det.Z()> Precision::Confusion())
-      prof = VSM.Z()/Det.Z();
+
+    if (Det.X() > Precision::Confusion())
+    {
+      prof = VSM.X() / Det.X();
+    }
+    else if (Det.Y() > Precision::Confusion())
+    {
+      prof = VSM.Y() / Det.Y();
+    }
+    else if (Det.Z() > Precision::Confusion())
+    {
+      prof = VSM.Z() / Det.Z();
+    }
   }
   else
   {
-    Standard_Real val1 = OPo.DotCross(Vtr[0],Vtr[2]);
-    Standard_Real val2 = Dir.DotCross(Vtr[0],Vtr[2]);
+    Standard_Real val1 = OPo.DotCross (Vtr[0], Vtr[2]);
+    Standard_Real val2 = Dir.DotCross (Vtr[0], Vtr[2]);
 
-    if(Abs(val2)>Precision::Confusion())
-      prof =val1/val2;
+    if (Abs (val2) > Precision::Confusion())
+    {
+      prof = val1 / val2;
+    }
   }
-  if (prof==Precision::Infinite())
+
+  if (prof == Precision::Infinite())
   {
-    prof= ElCLib::Parameter(EyeLine,P[0]);
-    prof = Min (prof, ElCLib::Parameter(EyeLine,P[1]));
-    prof = Min (prof, ElCLib::Parameter(EyeLine,P[2]));
+    prof= ElCLib::Parameter (thePickLine, P[0]);
+    prof = Min (prof, ElCLib::Parameter (thePickLine, P[1]));
+    prof = Min (prof, ElCLib::Parameter (thePickLine, P[2]));
   }
 
   return prof;
index ffd1c90..116859d 100755 (executable)
@@ -34,6 +34,7 @@ uses
     SensitiveEntity          from Select3D,
     SensitiveEntitySequence  from Select3D,
     ListOfBox2d              from SelectBasics,
+    PickArgs                 from SelectBasics,
     Array1OfPnt2d            from TColgp,
     Box2d                    from Bnd,
     Location                 from TopLoc
@@ -76,15 +77,15 @@ is
     ResetLocation(me:mutable) is redefined static;
        ---Purpose:  propagation of location on all the sensitive inside...    
 
-    Matches(me  :mutable; 
-            X,Y : Real from Standard;
-            aTol: Real from Standard;
-            DMin: out Real from Standard) 
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin, theMatchDepth : out Real from Standard)
     returns Boolean
-    is  redefined static;
-       ---Level: Public 
-       ---Purpose: projection of the sensitive primitive in order to
-       --          get 2D boxes for the Sort Algorithm
+    is redefined static;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking
+    -- detection area (close to the picking line).
+    -- For details please refer to base class declaration.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -101,10 +102,6 @@ is
        ---Level: Public 
     
 
-    ComputeDepth(me;EyeLine: Lin from gp) 
-    returns Real from Standard is redefined static;
-       ---Purpose: returns the depth of the touched entity
-
     MaxBoxes(me) returns Integer is redefined static;    
        ---Level: Public 
        ---Purpose:returns <mymaxrect>
@@ -114,9 +111,7 @@ is
 
     Set(me:mutable;TheOwnerId: EntityOwner from SelectBasics) is redefined static; 
     ---Purpose: Sets the owner for all entities in wire 
-        
-    SetLastPrj(me:mutable;aPrj: Projector from Select3D) is redefined virtual; 
-     
+
     GetLastDetected(me)
     returns SensitiveEntity from Select3D is static; 
     ---Purpose:returns <mymaxrect>
index 4131679..3554019 100755 (executable)
@@ -104,12 +104,12 @@ void Select3D_SensitiveWire::ResetLocation()
 // Function : Project
 // Purpose  :
 //=====================================================
-void Select3D_SensitiveWire
-::Project(const Handle(Select3D_Projector)& aProj)
+void Select3D_SensitiveWire::Project(const Handle(Select3D_Projector)& aProj)
 {
-  for(Standard_Integer i=1; i<=mysensitive.Length(); i++)
-    mysensitive(i)->Project(aProj);
-  Select3D_SensitiveEntity::Project(aProj);
+  for (Standard_Integer aSensIt = 1; aSensIt <= mysensitive.Length(); aSensIt++)
+  {
+    mysensitive (aSensIt)->Project (aProj);
+  }
 }
 
 //=====================================================
@@ -136,33 +136,37 @@ void Select3D_SensitiveWire
 // Function : Matches
 // Purpose  :
 //=====================================================
-Standard_Boolean Select3D_SensitiveWire
-::Matches(const Standard_Real X,
-          const Standard_Real Y,
-          const Standard_Real aTol,
-          Standard_Real& DMin)
+
+Standard_Boolean Select3D_SensitiveWire::Matches (const SelectBasics_PickArgs& thePickArgs,
+                                                  Standard_Real& theMatchDMin,
+                                                  Standard_Real& theMatchDepth)
 {
-  Standard_Integer i;
-  Standard_Real Dcur;
-  DMin = Precision::Infinite();
-  Standard_Boolean IsTouched = Standard_False;
-  for (i=1; i<=mysensitive.Length(); i++) 
+  theMatchDMin = RealLast();
+  theMatchDepth = RealLast();
+  Standard_Real aSegDMin, aSegDepth;
+  Standard_Boolean isMatched = Standard_False;
+  myDetectedIndex = -1;
+
+  for (Standard_Integer aSegIt = 1; aSegIt <= mysensitive.Length(); aSegIt++)
   {
-    if (mysensitive.Value(i)->Matches(X,Y,aTol,Dcur)) 
+    const Handle(SelectBasics_SensitiveEntity)& aSeg = mysensitive.Value (aSegIt);
+    if (!aSeg->Matches (thePickArgs, aSegDMin, aSegDepth))
     {
-      IsTouched = Standard_True;
-      if(Dcur<=DMin)
-      { 
-        myDetectedIndex = i; 
-        DMin = Dcur;
-      }
+      continue;
     }
+
+    isMatched = Standard_True;
+    if (aSegDMin > theMatchDMin)
+    {
+      continue;
+    }
+
+    myDetectedIndex = aSegIt;
+    theMatchDMin    = aSegDMin;
+    theMatchDepth   = aSegDepth;
   }
-  if ( ! IsTouched )
-    return Standard_False;
 
-  // compute and validate the depth (::Depth()) along the eyeline
-  return Select3D_SensitiveEntity::Matches(X,Y,aTol,DMin);
+  return isMatched;
 }
 
 //=====================================================
@@ -257,34 +261,6 @@ void Select3D_SensitiveWire::Dump(Standard_OStream& S,const Standard_Boolean Ful
 }
 
 //=======================================================================
-//function : ComputeDepth
-//purpose  :
-//=======================================================================
-
-Standard_Real Select3D_SensitiveWire::ComputeDepth(const gp_Lin& EyeLine) const
-{
-
-  if(myDetectedIndex==-1)
-    // should be never called...
-    return Precision::Infinite();
-  return mysensitive(myDetectedIndex)->ComputeDepth(EyeLine);
-
-}
-
-//=======================================================================
-//function : SetLastPrj
-//purpose  :
-//=======================================================================
-
-void Select3D_SensitiveWire::SetLastPrj(const Handle(Select3D_Projector)& Prj)
-{
-  Select3D_SensitiveEntity::SetLastPrj(Prj);
-  for(Standard_Integer i=1;i<=mysensitive.Length();i++)
-    mysensitive(i)->SetLastPrj(Prj);
-
-}
-
-//=======================================================================
 //function : GetEdges
 //purpose  : returns the sensitive edges stored in this wire
 //=======================================================================
diff --git a/src/SelectBasics/FILES b/src/SelectBasics/FILES
new file mode 100644 (file)
index 0000000..3649dd9
--- /dev/null
@@ -0,0 +1 @@
+SelectBasics_PickArgs.hxx
\ No newline at end of file
index fb6e855..d040c3f 100755 (executable)
@@ -69,6 +69,9 @@ is
     class ListOfSensitive instantiates List from TCollection 
     (SensitiveEntity);
 
+    imported PickArgs;
+    ---Purpose: Structure to provide all-in-one information on picking arguments
+    -- for "Matches" method of SelectBasics_SensitiveEntity.
 
     MaxOwnerPriority returns Integer;
     
diff --git a/src/SelectBasics/SelectBasics_PickArgs.hxx b/src/SelectBasics/SelectBasics_PickArgs.hxx
new file mode 100644 (file)
index 0000000..7dd4e52
--- /dev/null
@@ -0,0 +1,79 @@
+// Created on: 2013-09-04
+// Created by: Anton POLETAEV
+// Copyright (c) 2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 65 (the "License") You may not use the content of this file
+// except in compliance with the License Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file
+//
+// The Initial Developer of the Original Code is Open CASCADE SAS, having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License
+
+#ifndef _SelectBasics_PickArgs_HeaderFile
+#define _SelectBasics_PickArgs_HeaderFile
+
+#include <Standard_TypeDef.hxx>
+#include <gp_Lin.hxx>
+
+//! Structure to provide all-in-one information on picking arguments
+//! for "Matches" method of SelectBasics_SensitiveEntity.
+struct SelectBasics_PickArgs
+{
+public:
+
+  //! Constructor.
+  //! @param theX mouse picking coordinate on x-axis of selection coord space.
+  //! @param theY mouse picking coordinate on y-axis of selection coord space.
+  //! @param theTolerance x, y coordinate tolerance.
+  //! @param theDepthMin minimum picking depth in selection coord space.
+  //! @param theDepthMax maximum picking depth in selection coord space.
+  //! @param thePickingLine line going through picking point.
+  SelectBasics_PickArgs (const Standard_Real theX,
+                         const Standard_Real theY,
+                         const Standard_Real theTolerance,
+                         const Standard_Real theDepthMin,
+                         const Standard_Real theDepthMax,
+                         const gp_Lin& thePickingLine)
+  : myX (theX), myY (theY), myTolerance (theTolerance),
+    myDepthMin (theDepthMin), myDepthMax (theDepthMax),
+    myPickingLine (thePickingLine) {}
+
+public:
+
+  inline Standard_Real X() const { return myX; }
+
+  inline Standard_Real Y() const { return myY; }
+
+  inline Standard_Real Tolerance() const { return myTolerance; }
+
+  inline Standard_Real DepthMin() const { return myDepthMin; }
+
+  inline Standard_Real DepthMax() const { return myDepthMax; }
+
+  inline const gp_Lin& PickLine() const { return myPickingLine; }
+
+  //! @return True if passed depth lies outside valid depth range.
+  inline Standard_Boolean IsClipped(const Standard_Real theDepth) const
+  {
+    return (theDepth <= myDepthMin || theDepth >= myDepthMax);
+  }
+
+private:
+
+  Standard_Real myX;         //!< mouse picking coordinate on x-axis of selection coord space.
+  Standard_Real myY;         //!< mouse picking coordinate on y-axis of selection coord space.
+  Standard_Real myTolerance; //!< x, y coordinate tolerance
+  Standard_Real myDepthMin;  //!< minimum picking depth in selection coord space.
+  Standard_Real myDepthMax;  //!< maximum picking depth in selection coord space.
+  gp_Lin myPickingLine;      //!< line going through picking point
+};
+
+#endif
index 687efec..2b234d3 100755 (executable)
@@ -28,7 +28,8 @@ deferred class SensitiveEntity from SelectBasics inherits TShared from MMgt
 uses 
     EntityOwner,
     ListOfBox2d,
-    Array1OfPnt2d from TColgp, 
+    PickArgs,
+    Array1OfPnt2d from TColgp,
     Box2d from Bnd
 
 is
@@ -52,21 +53,49 @@ is
     ---Purpose: to be implemented specifically by each type of
     --          sensitive  primitive .
     --          
-    
-    Matches (me  :mutable; 
-             X,Y : Real from Standard;
-             aTol: Real from Standard;
-             DMin: out Real from Standard) 
-    returns Boolean
-    is deferred;
-    ---Level: Public 
-    ---Purpose: returns True if the object is very close to the
-    --          sensitive areas it gave to the selector...
-    --          returns the minimum distance found if no match;
-    --          
-    --          to be implemented specifically by each type of
-    --          sensitive  primitive .
-    
+
+    Matches (me : mutable;
+             thePickArgs : PickArgs from SelectBasics;
+             theMatchDMin : out Real from Standard;
+             theMatchDepth : out Real from Standard) returns Boolean is deferred;
+    ---Level: Public
+    ---Purpose: Checks whether the sensitive entity matches the picking detection
+    -- area (close to the picking line). This method takes into account depth
+    -- limits produced by abstract view: far/near planes, clippings.
+    -- Please port existing implementations of your picking detection, which
+    -- were done at Matches (X, Y, Tol, DMin) method to this one, introducing
+    -- the depth checks. Please note that the previous method is suppressed
+    -- and the virtual implementations are not used by OCC selection framework.
+    -- The porting procedure for simple sensitives (or if you are not interested
+    -- in implementing full scale depth checks) can be simplified to writing the
+    -- following code snippet:
+    -- @code
+    -- { // example code for porting descendants of Select3D_SensitiveEntity
+    --
+    --   // invoke implementation of obsolete matches method (if implemented)...
+    --   if (!Matches (thePickArgs.X(), thePickArgs.Y(), thePickArgs.Tolerance(), theMatchDMin))
+    --     return Standard_False;
+    --
+    --   // invoke your implementation of computing depth (if implemented)...
+    --   Standard_Real aDetectDepth = ComputeDepth (thePickArgs.PickLine());
+    --
+    --   return !thePickArgs.IsClipped(aDetectDepth);
+    -- }
+    -- @endcode
+    -- @param thePickArgs [in] the picking arguments.
+    -- @param theMatchDMin [out] the minimum distance on xy plane from point
+    -- of picking to center of gravity of the detected sub-part of sensitive
+    -- entity or the whole sensitive (e.g. used for resolving selection of
+    -- coinciding circles, selection will be set to the one whose center is
+    -- closest to the picking point).
+    -- @param theMatchDepth [out] the minimum detected depth: depth of the 
+    -- closest detected sub-part of sensitive entity (or the whole sensitive).
+    -- @return True if the sensitive matches the detection area.
+    -- This method is an entry point for picking detection framework.
+    -- The method is triggered when it is required to compose list of
+    -- detected sensitive entities. The sensitives are filtered out from
+    -- detection result if returned value is False. The passed entities are
+    -- then can be sorted by "theDetectDist", "theDetectDepth" parameters.
 
     Matches (me  :mutable; 
              XMin,YMin,XMax,YMax : Real from Standard;
@@ -96,10 +125,6 @@ is
     ---Purpose: returns True if able to give 3D information
     --          (Depth,...). See Select3D
     
-    Depth(me) returns Real from Standard is virtual;
-    ---Level: Internal 
-    ---Purpose:  Sort Selected entities according to depth...
-
     MaxBoxes(me) returns Integer is deferred;
     ---Purpose: returns the max number of boxes the entity is able to give
     --          at a time
index 98e32be..3516f08 100755 (executable)
@@ -39,7 +39,3 @@ void SelectBasics_SensitiveEntity
 
 const Handle(SelectBasics_EntityOwner)&  SelectBasics_SensitiveEntity
 ::OwnerId() const {return myOwnerId;}
-
-Standard_Real SelectBasics_SensitiveEntity::Depth() const
-{return 0.0;}
-
index 15d6fff..0e75a62 100755 (executable)
@@ -1,2 +1,2 @@
 SelectMgr_DataMapOfObjectOwners.hxx
-SelectMgr_CompareResults.hxx
+SelectMgr_CompareResults.hxx
\ No newline at end of file
index 30e4a16..57744a0 100755 (executable)
@@ -179,7 +179,8 @@ uses
     SelectBasics,
     PrsMgr,
     Prs3d,
-    Graphic3d
+    Graphic3d,
+    gp
 
 
 is
index 69e1054..924445b 100755 (executable)
@@ -76,9 +76,10 @@ uses
     SensitiveEntity              from SelectBasics,
     SortAlgo                     from SelectBasics,
     EntityOwner                  from SelectMgr,
-    StateOfSelection             from SelectMgr, 
-    Array1OfPnt2d                from TColgp
-    
+    StateOfSelection             from SelectMgr,
+    Array1OfPnt2d                from TColgp,
+    Lin                          from gp
+
 is
 
     Initialize ;
@@ -229,12 +230,12 @@ is
         ---C++: inline
 
 
-    Picked(me) returns any EntityOwner is static;
+    Picked(me) returns EntityOwner from SelectMgr is static;
        ---Level: Public 
        ---Purpose: Returns the current selected entity detected by the selector;
 
 
-    OnePicked(me:mutable) returns any EntityOwner is static;
+    OnePicked(me:mutable) returns EntityOwner from SelectMgr is static;
        ---Purpose: Returns the picked element with the highest priority,
        -- and which is the closest to the last successful mouse position.
 
@@ -350,6 +351,54 @@ is
     SetUpdateSortPossible( me: mutable; possible : Boolean from Standard );
     IsUpdateSortPossible( me )  returns Boolean from Standard;
 
+    PickingLine (me; theX, theY : Real from Standard)
+      returns Lin from gp
+      is virtual protected;
+    ---Level: Internal
+    ---Purpose: Returns picking line along which the depth value should be
+    -- computed. Override this method to compute picking line by the same
+    -- which is used for projecting sensitive entities to selection space.
+    -- @param theX [in] the x picking coordinate.
+    -- @param theY [in] the y picking coordinate.
+    -- @return picking line.
+
+    DepthClipping (me; theX, theY : Real from Standard;
+                   theMin, theMax : out Real from Standard)
+      is virtual protected;
+    ---Level: Internal
+    ---Purpose: Returns global depth clipping limits applied to every sensitive.
+    -- Override this method to convert clippings defined by application into
+    -- selection space for mouse picking detection.
+    -- Default implementation returns infinite clip limits (no clipping).
+    -- @param theX [in] the x picking coordinate.
+    -- @param theY [in] the y picking coordinate.
+    -- @param theMin [out] the minimum depth. Default is RealFirst()
+    -- @param theMax [out] the maximum depth. Default is RealLast()
+
+    DepthClipping (me; theX, theY : Real from Standard;
+                   theOwner : EntityOwner from SelectMgr;
+                   theMin, theMax : out Real from Standard)
+      is virtual protected;
+    ---Level: Internal
+    ---Purpose: Returns depth clipping limits applied to sensitives of
+    -- entity owner. Override this method to convert clippings defined by
+    -- application owners into selection space for mouse picking detection.
+    -- Default implementation returns infinite clip limits (no clipping).
+    -- @param theX [in] the x picking coordinate.
+    -- @param theY [in] the y picking coordinate.
+    -- @param theOwner [in] the sensitive owner.
+    -- @param theMin [out] the minimum depth. Default is RealFirst()
+    -- @param theMax [out] the maximum depth. Default is RealLast()
+
+    HasDepthClipping (me; theOwner : EntityOwner from SelectMgr)
+      returns Boolean is virtual protected;
+    ---Level: Internal
+    ---Purpose: Returns True if the owner provides clipping by depth
+    -- for its sensitives. Override this method to tell the selector
+    -- to use the DepthClipping method for the owner.
+    -- Default implementation returns False for every owner.
+    -- @param theOwner [in] the onwer to check.
+    -- @return True if owner provides depth limits for sensitive clipping.
 
 fields
 
index 289119b..6eb88d7 100755 (executable)
 #include <Precision.hxx>
 #include <TColStd_Array1OfInteger.hxx>
 #include <TCollection_AsciiString.hxx>
+#include <NCollection_DataMap.hxx>
+#include <SelectBasics_EntityOwner.hxx>
 #include <SelectBasics_ListIteratorOfListOfBox2d.hxx>
 #include <SelectBasics_SensitiveEntity.hxx>
-#include <SelectBasics_EntityOwner.hxx>
 #include <SelectBasics_ListOfBox2d.hxx>
+#include <SelectBasics_PickArgs.hxx>
 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
 #include <SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation.hxx>
 #include <SelectMgr_SortCriterion.hxx>
-#include <Select3D_SensitiveEntity.hxx>
 #include <SortTools_QuickSortOfInteger.hxx>
 #include <OSD_Environment.hxx>
 
@@ -51,10 +52,34 @@ static Standard_Boolean SelectDebugModeOnVS()
     OSD_Environment selectdb("SELDEBUGMODE");
     if ( selectdb.Value().IsEmpty() )
       isDebugMode = 0;
-  }                       
+  }
   return ( isDebugMode != 0 );
 }
 
+namespace
+{
+  // container to store depth limits in collection map
+  struct SelectMgr_DepthRange
+  {
+    Standard_Real DepthMin;
+    Standard_Real DepthMax;
+    Standard_Boolean IsEmpty() const { return (DepthMin == DepthMax); }
+
+    void Common (const SelectMgr_DepthRange& theOther)
+    {
+      if (theOther.DepthMin > DepthMax || theOther.DepthMax < DepthMin)
+      {
+        DepthMin = RealFirst();
+        DepthMax = RealLast();
+        return;
+      }
+
+      DepthMin = Max (DepthMin, theOther.DepthMin);
+      DepthMax = Min (DepthMax, theOther.DepthMax);
+    }
+  };
+};
+
 //==================================================
 // Function: Initialize
 // Purpose :
@@ -85,7 +110,7 @@ Activate (const Handle(SelectMgr_Selection)& aSelection,
   if (!myselections.IsBound(aSelection))
   {
     myselections.Bind(aSelection,0);
-  } 
+  }
   else if (myselections(aSelection)!=0)
   {
     myselections(aSelection)= 0;
@@ -124,11 +149,11 @@ UpdateSort();
 }
 //=======================================================================
 //function : Sleep
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SelectMgr_ViewerSelector::Sleep(const Handle(SelectMgr_SelectableObject)& SO)
-{ 
+{
 
   for(SO->Init();SO->More();SO->Next()){
     if(myselections.IsBound(SO->CurrentSelection())){
@@ -243,7 +268,7 @@ void SelectMgr_ViewerSelector::UpdateSort()
       if(It.Value()== 0)
       { curEntity = It.Key();
       for(curEntity->Init();curEntity->More();curEntity->Next())
-      {     
+      {
         static SelectBasics_ListOfBox2d BoxList;
         BoxList.Clear();
         curEntity->Sensitive()->Areas(BoxList);
@@ -395,7 +420,7 @@ void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly)
   if (toupdate) UpdateConversion();
   if (tosort)   UpdateSort();
   if (myactivenb!=0){
-    // the Bnd boxes are used for the first time  
+    // the Bnd boxes are used for the first time
     Bnd_Box2d aBox;
     Standard_Integer NbPnt = aPoly.Length();
     Standard_Integer i;
@@ -411,66 +436,113 @@ void SelectMgr_ViewerSelector::InitSelect(const TColgp_Array1OfPnt2d& aPoly)
 
 //==================================================
 // Function: LoadResult
-// Purpose : for the moment the size of the primitive 
+// Purpose : for the moment the size of the primitive
 //           is not taken into account in the search criteriai...
 //           The priority, the depth and the min. distance to CDG or Borders is taken...
 //==================================================
-void SelectMgr_ViewerSelector::
-LoadResult()
+void SelectMgr_ViewerSelector::LoadResult()
 {
-  //  Handle(SelectMgr_EntityOwner)  OWNR;  
-  if(myselector.More())
+  if (myselector.More())
   {
-    //      Standard_Boolean Found(Standard_False);
-    Standard_Real DMin;
-    Standard_Integer nument;
-    for(;myselector.More();myselector.Next()){
-      nument = myselector.Value();
-      const Handle(SelectBasics_SensitiveEntity)& SE = myentities(nument);
-      if (SE->Matches(lastx,lasty,mytolerance,DMin)) { 
-        const Handle(SelectBasics_EntityOwner)& OWNR = SE->OwnerId();
+    NCollection_DataMap<Handle(SelectMgr_EntityOwner), SelectMgr_DepthRange> aMapOfOwnerRanges;
 
-        if(!OWNR.IsNull()){
-          Standard_Real TheDepth = SE->Depth();
-          Standard_Integer Prior = OWNR->Priority();
+    // collect information on depth clipping from implementations
+    gp_Lin aPickLine = PickingLine (lastx, lasty);
+    SelectMgr_DepthRange aViewDRange;
+    DepthClipping (lastx, lasty, aViewDRange.DepthMin, aViewDRange.DepthMax);
+
+    Standard_Real aDMin;
+    Standard_Real aDepthMin;
+    Standard_Integer aNument;
+
+    if (!aViewDRange.IsEmpty())
+    {
+      for (; myselector.More(); myselector.Next())
+      {
+        aNument = myselector.Value();
+
+        const Handle(SelectBasics_SensitiveEntity)& SE = myentities (aNument);
+        const Handle(SelectMgr_EntityOwner)& anOwner =
+          Handle(SelectMgr_EntityOwner)::DownCast (SE->OwnerId());
+
+        // compute depth range for sensitives of entity owner
+        SelectMgr_DepthRange anEntityDRange (aViewDRange);
+        if (!anOwner.IsNull() && HasDepthClipping (anOwner) && !aMapOfOwnerRanges.Find (anOwner, anEntityDRange))
+        {
+          // get depth range from implementation
+          SelectMgr_DepthRange aGetRange;
+          DepthClipping (lastx, lasty, anOwner, aGetRange.DepthMin, aGetRange.DepthMax);
+
+          // concatenate and remember depth range for pefromance increase
+          anEntityDRange.Common (aGetRange);
+          aMapOfOwnerRanges.Bind (anOwner, anEntityDRange);
+        }
+
+        if (anEntityDRange.IsEmpty())
+        {
+          continue;
+        }
 
-          SelectMgr_SortCriterion SC(Prior,TheDepth,DMin,mytolerance,preferclosest);
-          if ( mystored.Contains(OWNR) )
+        SelectBasics_PickArgs aPickArgs (lastx, lasty, mytolerance,
+                                         anEntityDRange.DepthMin,
+                                         anEntityDRange.DepthMax,
+                                         aPickLine);
+
+        if (SE->Matches (aPickArgs, aDMin, aDepthMin))
+        {
+          if (!anOwner.IsNull())
           {
-            SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey(OWNR);
-            if ( SC > Crit )
-            {
-              Crit = SC;
+            Standard_Integer aPrior = anOwner->Priority();
 
-              // update previously recorded entity for this owner
-              for (int i=1; i <= myprim.Length(); i++)
-                if (myentities(myprim(i))->OwnerId() == OWNR) {
-                  myprim.SetValue (i, nument);
-                  break;
+            SelectMgr_SortCriterion SC (aPrior, aDepthMin, aDMin, mytolerance, preferclosest);
+            if (mystored.Contains (anOwner))
+            {
+              SelectMgr_SortCriterion& Crit = mystored.ChangeFromKey (anOwner);
+              if (SC > Crit)
+              {
+                Crit = SC;
+
+                // update previously recorded entity for this owner
+                for (int i = 1; i <= myprim.Length(); i++)
+                {
+                  if (myentities (myprim(i))->OwnerId() == anOwner)
+                  {
+                    myprim.SetValue (i, aNument);
+                    break;
+                  }
                 }
+              }
             }
-          }
-          else
-          {
-            mystored.Add(OWNR,SC);
+            else
+            {
+              mystored.Add (anOwner, SC);
 
-            // record entity
-            myprim.Append(nument);
+              // record entity
+              myprim.Append (aNument);
+            }
           }
         }
       }
     }
+
     SortResult();
   }
-  if( SelectDebugModeOnVS() ){
+
+  if (SelectDebugModeOnVS())
+  {
     cout<<"\tSelectMgr_VS:: Resultat du move"<<endl;
     cout<<"\tNb Detectes :"<<mystored.Extent()<<endl;
-    for(Standard_Integer i=1;i<=mystored.Extent();i++){
-      const SelectMgr_SortCriterion& Crit = mystored(myIndexes->Value(i));
-      cout<<"\t"<<i<<" - Prior"<<Crit.Priority()<<" - prof :"<<Crit.Depth()<<"  - Dist. :"<<Crit.MinDist()<<endl;
+
+    for(Standard_Integer i=1; i<=mystored.Extent(); i++)
+    {
+      const SelectMgr_SortCriterion& Crit = mystored (myIndexes->Value(i));
+      cout << "\t" << i << " - Prior" << Crit.Priority()
+           << " - prof :" << Crit.Depth()
+           << "  - Dist. :" << Crit.MinDist() << endl;
     }
   }
 }
+
 //==================================================
 // Function: LoadResult
 // Purpose :
@@ -479,7 +551,7 @@ void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox)
 {
   mystored.Clear();
 
-  //  Handle(SelectMgr_EntityOwner)  OWNR;  
+  //  Handle(SelectMgr_EntityOwner)  OWNR;
   if(myselector.More())
   { Standard_Real xmin,ymin,xmax,ymax;
   abox.Get(xmin,ymin,xmax,ymax);
@@ -503,17 +575,17 @@ void SelectMgr_ViewerSelector::LoadResult(const Bnd_Box2d& abox)
   }
 
   // do not parse in case of selection by elastic rectangle (BUG ANALYST)
-  if(mystored.IsEmpty()) return; 
-  if(myIndexes.IsNull()) 
-    myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); 
-  else if(mystored.Extent() !=myIndexes->Length()) 
-    myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); 
+  if(mystored.IsEmpty()) return;
+  if(myIndexes.IsNull())
+    myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
+  else if(mystored.Extent() !=myIndexes->Length())
+    myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
 
-  // to work faster... 
-  TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); 
-  for(Standard_Integer I=1;I<=mystored.Extent();I++) 
-    thearr(I)=I; 
-  } 
+  // to work faster...
+  TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
+  for(Standard_Integer I=1;I<=mystored.Extent();I++)
+    thearr(I)=I;
+  }
 }
 //==================================================
 // Function: LoadResult
@@ -529,9 +601,9 @@ void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly)
     aBox.Update(aPoly(i).X(),aPoly(i).Y());
   }
   Standard_Integer NB=0;
-  //  Handle(SelectMgr_EntityOwner)  OWNR;  
+  //  Handle(SelectMgr_EntityOwner)  OWNR;
   if(myselector.More())
-  { 
+  {
     Standard_Integer nument;
 
     for(;myselector.More();myselector.Next()){
@@ -551,16 +623,16 @@ void SelectMgr_ViewerSelector::LoadResult(const TColgp_Array1OfPnt2d& aPoly)
       }
     }
 
-    if(mystored.IsEmpty()) return; 
-    if(myIndexes.IsNull()) 
-      myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent()); 
-    else if(mystored.Extent() !=myIndexes->Length()) 
-      myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent()); 
+    if(mystored.IsEmpty()) return;
+    if(myIndexes.IsNull())
+      myIndexes = new TColStd_HArray1OfInteger(1,mystored.Extent());
+    else if(mystored.Extent() !=myIndexes->Length())
+      myIndexes = new TColStd_HArray1OfInteger (1,mystored.Extent());
 
-    // to work faster... 
-    TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1(); 
-    for(Standard_Integer I=1;I<=mystored.Extent();I++) 
-      thearr(I)=I; 
+    // to work faster...
+    TColStd_Array1OfInteger& thearr = myIndexes->ChangeArray1();
+    for(Standard_Integer I=1;I<=mystored.Extent();I++)
+      thearr(I)=I;
   }
 }
 
@@ -599,9 +671,9 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
 
 //=======================================================================
 //function : More
-//purpose  : 
+//purpose  :
 //=======================================================================
-Standard_Boolean SelectMgr_ViewerSelector::More() 
+Standard_Boolean SelectMgr_ViewerSelector::More()
 {
   if(mystored.Extent()==0) return Standard_False;
   if(myCurRank==0) return Standard_False;
@@ -633,7 +705,7 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector
 
 //=======================================================================
 //function : NbPicked
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
@@ -642,12 +714,12 @@ Standard_Integer SelectMgr_ViewerSelector::NbPicked() const
 }
 //=======================================================================
 //function : Picked
-//purpose  : 
+//purpose  :
 //=======================================================================
 Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_Integer aRank) const
 {
 
-  Handle(SelectMgr_EntityOwner) Own; 
+  Handle(SelectMgr_EntityOwner) Own;
   if (aRank<1 || aRank>NbPicked())
     return Own;
   Standard_Integer Indx = myIndexes->Value(aRank);
@@ -659,7 +731,7 @@ Handle(SelectMgr_EntityOwner) SelectMgr_ViewerSelector::Picked(const Standard_In
 }
 //=======================================================================
 //function : Primitive
-//purpose  : 
+//purpose  :
 //=======================================================================
 Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive
 (const Standard_Integer /*Index*/) const
@@ -674,7 +746,7 @@ Handle(SelectBasics_SensitiveEntity) SelectMgr_ViewerSelector::Primitive
 //==================================================
 void SelectMgr_ViewerSelector::LastPosition(Standard_Real& Xlast,
                                             Standard_Real& YLast) const
-{   Xlast = lastx;YLast = lasty;} 
+{   Xlast = lastx;YLast = lasty;}
 
 
 
@@ -711,7 +783,7 @@ Standard_Integer SelectMgr_ViewerSelector::NbBoxes()
 
 //==================================================
 // Function: Contains
-// Purpose : 
+// Purpose :
 //==================================================
 Standard_Boolean SelectMgr_ViewerSelector::
 Contains(const Handle(SelectMgr_SelectableObject)& anObject) const
@@ -734,14 +806,14 @@ Contains(const Handle(SelectMgr_SelectableObject)& anObject) const
 Standard_Boolean SelectMgr_ViewerSelector::
 Modes(const Handle(SelectMgr_SelectableObject)& SO,
       TColStd_ListOfInteger& TheActiveList,
-      const SelectMgr_StateOfSelection WantedState) const 
+      const SelectMgr_StateOfSelection WantedState) const
 {
   Standard_Boolean Found= Standard_False;
   for(SO->Init();SO->More();SO->Next()){
     if(myselections.IsBound(SO->CurrentSelection())){
       if(WantedState==SelectMgr_SOS_Any)
         TheActiveList.Append(SO->CurrentSelection()->Mode());
-      else if( myselections(SO->CurrentSelection())==WantedState) 
+      else if( myselections(SO->CurrentSelection())==WantedState)
         TheActiveList.Append(SO->CurrentSelection()->Mode());
 
       if(!Found) Found=Standard_True;
@@ -757,8 +829,8 @@ IsActive(const Handle(SelectMgr_SelectableObject)& SO,
 {
   for(SO->Init();SO->More();SO->Next()){
     if(aMode==SO->CurrentSelection()->Mode()){
-      if(myselections.IsBound(SO->CurrentSelection()) && 
-        myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated) 
+      if(myselections.IsBound(SO->CurrentSelection()) &&
+        myselections(SO->CurrentSelection())==SelectMgr_SOS_Activated)
         return Standard_True;
       else return Standard_False;
     }
@@ -784,10 +856,10 @@ IsInside(const Handle(SelectMgr_SelectableObject)& SO,
 
 //=======================================================================
 //function : Status
-//purpose  : 
+//purpose  :
 //=======================================================================
 
-SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const 
+SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectMgr_Selection)& aSel) const
 {
   if(!myselections.IsBound(aSel)) return SelectMgr_SOS_Unknown;
   //JR/Hp
@@ -801,7 +873,7 @@ SelectMgr_StateOfSelection SelectMgr_ViewerSelector::Status(const Handle(SelectM
 
 //=======================================================================
 //function : Dump
-//purpose  : 
+//purpose  :
 //=======================================================================
 
 void SelectMgr_ViewerSelector::Dump(Standard_OStream& S) const
@@ -828,10 +900,10 @@ Status(const Handle(SelectMgr_SelectableObject)& SO) const
     if(myselections.IsBound(SO->CurrentSelection()))
     {
       Found = Standard_True;
-      Status = Status + "Mode " + 
+      Status = Status + "Mode " +
         TCollection_AsciiString(SO->CurrentSelection()->Mode()) +
         " present - " ;
-      if(myselections(SO->CurrentSelection())) 
+      if(myselections(SO->CurrentSelection()))
         Status = Status + " Active \n\t";
       else
         Status = Status + " Inactive \n\t";
@@ -844,15 +916,15 @@ Status(const Handle(SelectMgr_SelectableObject)& SO) const
 
 
 TCollection_AsciiString SelectMgr_ViewerSelector::
-Status () const 
+Status () const
 {
-  // sevsitive primitives present 
+  // sevsitive primitives present
   //-----------------------------
   TCollection_AsciiString Status("\t\tSelector Status :\n\t");
   // selections
   //-----------
   Standard_Integer NbActive =0,NbPrim=0;
-  Status = Status + "Number of already computed selections : " + 
+  Status = Status + "Number of already computed selections : " +
     TCollection_AsciiString(myselections.Extent());
 
   SelectMgr_DataMapIteratorOfDataMapOfSelectionActivation It(myselections);
@@ -863,7 +935,7 @@ Status () const
     }
   }
   Status = Status + " - " + TCollection_AsciiString(NbActive) + " activated ones\n\t";
-  Status = Status + "Number of active sensitive primitives : " + 
+  Status = Status + "Number of active sensitive primitives : " +
     TCollection_AsciiString(NbPrim)+"\n\t";
   Status = Status + "Real stored Pick Tolerance : " + TCollection_AsciiString(mytolerance) +"\n\t";
   if(toupdate) {
@@ -875,13 +947,13 @@ Status () const
 
 //=======================================================================
 //function : SortResult
-//purpose  :  there is a certain number of entities ranged by criteria 
+//purpose  :  there is a certain number of entities ranged by criteria
 //            (depth, size, priority, mouse distance from borders or
 //            CDG of the detected primitive. Parsing :
 //             maximum priorities .
 //             then a reasonable compromise between depth and distance...
 // finally the ranges are stored in myindexes depending on the parsing.
-// so, it is possible to only read 
+// so, it is possible to only read
 //=======================================================================
 void SelectMgr_ViewerSelector::SortResult()
 {
@@ -946,7 +1018,7 @@ void SelectMgr_ViewerSelector::SortResult()
 
 //=======================================================================
 //function :
-//purpose  : 
+//purpose  :
 //=======================================================================
 Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const
 {
@@ -955,9 +1027,55 @@ Standard_Boolean SelectMgr_ViewerSelector::IsUpdateSortPossible() const
 
 //=======================================================================
 //function :
-//purpose  : 
+//purpose  :
 //=======================================================================
 void SelectMgr_ViewerSelector::SetUpdateSortPossible( const Standard_Boolean possible )
 {
   myUpdateSortPossible = possible;
 }
+
+//=======================================================================
+//function : PickingLine
+//purpose  : Stub
+//=======================================================================
+gp_Lin SelectMgr_ViewerSelector::PickingLine (const Standard_Real /*theX*/,
+                                              const Standard_Real /*theY*/) const
+{
+  return gp_Lin();
+}
+
+//=======================================================================
+//function : DepthClipping
+//purpose  : Stub
+//=======================================================================
+void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
+                                              const Standard_Real /*theY*/,
+                                              Standard_Real& theMin,
+                                              Standard_Real& theMax) const
+{
+  theMin = RealFirst();
+  theMax = RealLast();
+}
+
+//=======================================================================
+//function : DepthClipping
+//purpose  : Stub
+//=======================================================================
+void SelectMgr_ViewerSelector::DepthClipping (const Standard_Real /*theX*/,
+                                              const Standard_Real /*theY*/,
+                                              const Handle(SelectMgr_EntityOwner)& /*theOwner*/,
+                                              Standard_Real& theMin,
+                                              Standard_Real& theMax) const
+{
+  theMin = RealFirst();
+  theMax = RealLast();
+}
+
+//=======================================================================
+//function : HasDepthClipping
+//purpose  : Stub
+//=======================================================================
+Standard_Boolean SelectMgr_ViewerSelector::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& /*theOwner*/) const
+{
+  return Standard_False;
+}
index 832ff86..55c93f1 100755 (executable)
@@ -30,12 +30,15 @@ class ViewerSelector3d from StdSelect inherits ViewerSelector from SelectMgr
 uses
     View      from V3d,
     Selection from SelectMgr,
+    EntityOwner from SelectMgr,
     Projector from Select3D,
     Group     from Graphic3d,
     Structure from Graphic3d,
+    SetOfHClipPlane from Graphic3d,
     Array1OfReal    from TColStd, 
     Array1OfPnt2d from TColgp,
-    SensitivityMode from StdSelect
+    SensitivityMode from StdSelect,
+    Lin from gp
 
 is
 
@@ -106,10 +109,6 @@ is
     ---Category: Internal Methods
     --           -----------------
 
-    ReactivateProjector(me:mutable);
-       ---Level: Internal 
-       ---Purpose: Puts back the address of the current projector in sensitive primitives...
-
     UpdateProj(me   :mutable;
               aView: View from V3d) returns Boolean is static private;
        ---Level: Internal 
@@ -153,9 +152,46 @@ is
      is static private;
        ---Level: Internal 
 
-       
-
-
+    SetClipping (me : mutable; thePlanes : SetOfHClipPlane from Graphic3d) is protected;
+    ---Level: Internal
+    ---Purpose: Set view clipping for the selector.
+    -- @param thePlanes [in] the view planes.
+
+    ComputeClipRange (me; thePlanes : SetOfHClipPlane from Graphic3d;
+                      thePickLine : Lin from gp;
+                      theDepthMin, theDepthMax : out Real from Standard)
+      is protected;
+    ---Level: Internal
+    ---Purpose: Computed depth boundaries for the passed set of clipping planes and picking line.
+    -- @param thePlanes [in] the planes.
+    -- @param thePickLine [in] the picking line.
+    -- @param theDepthMin [out] minimum depth limit.
+    -- @param theDepthMax [out] maximum depth limit.
+
+    PickingLine (me; theX, theY : Real from Standard)
+      returns Lin from gp
+      is redefined protected;
+    ---Level: Internal
+    ---Purpose: For more details please refer to base class.
+
+    DepthClipping (me; theX, theY : Real from Standard;
+                   theMin, theMax : out Real from Standard)
+      is redefined protected;
+    ---Level: Internal
+    ---Purpose: For more details please refer to base class.
+
+    DepthClipping (me; theX, theY : Real from Standard;
+                   theOwner : EntityOwner from SelectMgr;
+                   theMin, theMax : out Real from Standard)
+      is redefined protected;
+    ---Level: Internal
+    ---Purpose: For more details please refer to base class.
+
+    HasDepthClipping (me; theOwner : EntityOwner from SelectMgr)
+      returns Boolean is redefined protected;
+    ---Level: Internal
+    ---Purpose: For more details please refer to base class.
+    
 fields
 
     myprj         : Projector    from Select3D;
@@ -174,8 +210,8 @@ fields
     myareagroup : Group            from Graphic3d;
     mysensgroup : Group            from Graphic3d;
     mystruct: Structure        from Graphic3d;
+    myClipPlanes : SetOfHClipPlane from Graphic3d;
 
-    
 end ViewerSelector3d;
 
 
index 87885ce..1c88fce 100755 (executable)
 #include <gp_Dir.hxx>
 #include <gp_Ax3.hxx>
 #include <gp_GTrsf.hxx>
+#include <gp_Pln.hxx>
 #include <V3d_PerspectiveView.hxx>
-#include <V3d_Plane.hxx>
 #include <Select3D_SensitiveEntity.hxx>
 #include <Graphic3d_ArrayOfPolylines.hxx>
+#include <Graphic3d_SetOfHClipPlane.hxx>
+#include <SelectMgr_SelectableObject.hxx>
 #include <SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive.hxx>
 #include <SelectBasics_ListOfBox2d.hxx>
 #include <Visual3d_TransientManager.hxx>
@@ -197,57 +199,13 @@ void StdSelect_ViewerSelector3d
        const Standard_Integer YPix,
        const Handle(V3d_View)& aView)
 {
+  SetClipping (aView->GetClipPlanes());
   UpdateProj(aView);
   Standard_Real Xr3d,Yr3d,Zr3d;
   gp_Pnt2d P2d;
   aView->Convert(XPix,YPix,Xr3d,Yr3d,Zr3d);
   myprj->Project(gp_Pnt(Xr3d,Yr3d,Zr3d),P2d);
 
-  // compute depth limits if clipping plane(s) enabled
-  gp_Lin anEyeLine = myprj->Shoot (P2d.X(), P2d.Y());
-  Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
-  Standard_Real aDepthFrom = ShortRealFirst();
-  Standard_Real aDepthTo   = ShortRealLast();
-  for (aView->InitActivePlanes(); aView->MoreActivePlanes(); aView->NextActivePlanes())
-  {
-    aView->ActivePlane()->Plane (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
-    const gp_Dir& anEyeLineDir  = anEyeLine.Direction();
-    gp_Dir aPlaneNormal (aPlaneA, aPlaneB, aPlaneC);
-
-    Standard_Real aDotProduct = anEyeLineDir.Dot (aPlaneNormal);
-    Standard_Real aDirection = -(aPlaneD + anEyeLine.Location().XYZ().Dot (aPlaneNormal.XYZ()));
-    if (Abs (aDotProduct) < Precision::Angular())
-    {
-      // eyeline parallel to the clipping plane
-      if (aDirection > 0.0)
-      {
-        // invalidate the interval
-        aDepthTo   = ShortRealFirst();
-        aDepthFrom = ShortRealFirst();
-        break;
-      }
-      // just ignore this plane
-      continue;
-    }
-
-    // compute distance along the eyeline from eyeline location to intersection with clipping plane
-    Standard_Real aDepth = aDirection / aDotProduct;
-
-    // reduce depth limits
-    if (aDotProduct < 0.0)
-    {
-      if (aDepth < aDepthTo)
-      {
-        aDepthTo = aDepth;
-      }
-    }
-    else if (aDepth > aDepthFrom)
-    {
-      aDepthFrom = aDepth;
-    }
-  }
-  myprj->DepthMinMax (aDepthFrom, aDepthTo);
-
   InitSelect(P2d.X(),P2d.Y());
 }
 
@@ -1087,18 +1045,123 @@ void StdSelect_ViewerSelector3d::ComputeAreasPrs (const Handle(SelectMgr_Selecti
 }
 
 //=======================================================================
-//function : ReactivateProjector
+//function : SetClipping
 //purpose  :
 //=======================================================================
-void StdSelect_ViewerSelector3d::ReactivateProjector()
+void StdSelect_ViewerSelector3d::SetClipping (const Graphic3d_SetOfHClipPlane& thePlanes)
 {
-  Handle(SelectBasics_SensitiveEntity) BS;
-  for (SelectMgr_DataMapIteratorOfDataMapOfIntegerSensitive it (myentities); it.More(); it.Next())
+  myClipPlanes = thePlanes;
+}
+
+//=======================================================================
+//function : ComputeClipRange
+//purpose  :
+//=======================================================================
+void StdSelect_ViewerSelector3d::ComputeClipRange (const Graphic3d_SetOfHClipPlane& thePlanes,
+                                                   const gp_Lin& thePickLine,
+                                                   Standard_Real& theDepthMin,
+                                                   Standard_Real& theDepthMax) const
+{
+  theDepthMin = RealFirst();
+  theDepthMax = RealLast();
+  Standard_Real aPlaneA, aPlaneB, aPlaneC, aPlaneD;
+
+  Graphic3d_SetOfHClipPlane::Iterator aPlaneIt (thePlanes);
+  for (; aPlaneIt.More(); aPlaneIt.Next())
   {
-    BS = it.Value();
-    if (BS->Is3D())
+    const Handle(Graphic3d_ClipPlane)& aClipPlane = aPlaneIt.Value();
+    if (!aClipPlane->IsOn())
+      continue;
+
+    gp_Pln aGeomPlane = aClipPlane->ToPlane();
+
+    aGeomPlane.Coefficients (aPlaneA, aPlaneB, aPlaneC, aPlaneD);
+
+    const gp_Dir& aPlaneDir = aGeomPlane.Axis().Direction();
+    const gp_Dir& aPickDir  = thePickLine.Direction();
+    const gp_XYZ& aPntOnLine = thePickLine.Location().XYZ();
+    const gp_XYZ& aPlaneDirXYZ = aPlaneDir.XYZ();
+
+    Standard_Real aDotProduct = aPickDir.Dot (aPlaneDir);
+    Standard_Real aDistance = -(aPntOnLine.Dot (aPlaneDirXYZ) + aPlaneD);
+
+    // check whether the pick line is parallel to clip plane
+    if (Abs (aDotProduct) < Precision::Angular())
     {
-      (*((Handle(Select3D_SensitiveEntity)*) &BS))->SetLastPrj (myprj);
+      if (aDistance > 0.0)
+      {
+        // line lies above the plane, thus no selection is possible
+        theDepthMin = 0.0;
+        theDepthMax = 0.0;
+        return;
+      }
+
+      // line lies below the plane and is not clipped, skip
+      continue;
+    }
+
+    // compute distance to point of pick line intersection with the plane
+    Standard_Real aIntDist = aDistance / aDotProduct;
+
+    // change depth limits for case of opposite and directed planes
+    if (aDotProduct < 0.0)
+    {
+      theDepthMax = Min (aIntDist, theDepthMax);
+    }
+    else if (aIntDist > theDepthMin)
+    {
+      theDepthMin = Max (aIntDist, theDepthMin);
     }
   }
 }
+
+//=======================================================================
+//function : PickingLine
+//purpose  :
+//=======================================================================
+gp_Lin StdSelect_ViewerSelector3d::PickingLine(const Standard_Real theX, const Standard_Real theY) const
+{
+  return myprj->Shoot (theX, theY);
+}
+
+//=======================================================================
+//function : DepthClipping
+//purpose  :
+//=======================================================================
+void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
+                                                const Standard_Real theY,
+                                                Standard_Real& theDepthMin,
+                                                Standard_Real& theDepthMax) const
+{
+  return ComputeClipRange (myClipPlanes, PickingLine (theX, theY), theDepthMin, theDepthMax);
+}
+
+//=======================================================================
+//function : DepthClipping
+//purpose  :
+//=======================================================================
+void StdSelect_ViewerSelector3d::DepthClipping (const Standard_Real theX,
+                                                const Standard_Real theY,
+                                                const Handle(SelectMgr_EntityOwner)& theOwner,
+                                                Standard_Real& theDepthMin,
+                                                Standard_Real& theDepthMax) const
+{
+  return ComputeClipRange (theOwner->Selectable()->GetClipPlanes(),
+                           PickingLine (theX, theY),
+                           theDepthMin, theDepthMax);
+}
+
+//=======================================================================
+//function : HasDepthClipping
+//purpose  :
+//=======================================================================
+Standard_Boolean StdSelect_ViewerSelector3d::HasDepthClipping (const Handle(SelectMgr_EntityOwner)& theOwner) const
+{
+  if (!theOwner->HasSelectable())
+  {
+    return Standard_False;
+  }
+
+  const Handle(SelectMgr_SelectableObject)& aSelectable = theOwner->Selectable();
+  return (aSelectable->GetClipPlanes().Size() > 0);
+}
index e07ede2..4d211e0 100755 (executable)
@@ -10,3 +10,5 @@ V3d_Viewer_3.cxx
 V3d_Viewer_4.cxx
 V3d_View_Print.cxx
 V3d_View_5.cxx
+V3d_Plane.hxx
+V3d_Plane.cxx
\ No newline at end of file
index f52e78b..5ff965a 100755 (executable)
@@ -213,9 +213,6 @@ is
         class SpotLight;
         ---Purpose: Services of spot light sources.
 
-        class Plane;
-        ---Pupose: Services of any kind of clipping plane.
-
         ---------------------------------
         ---Category: Instantiated classes
         ---------------------------------
diff --git a/src/V3d/V3d_Plane.cdl b/src/V3d/V3d_Plane.cdl
deleted file mode 100755 (executable)
index 30de000..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
--- Created on: 1992-01-17
--- Created by: GG
--- Copyright (c) 1992-1999 Matra Datavision
--- Copyright (c) 1999-2012 OPEN CASCADE SAS
---
--- The content of this file is subject to the Open CASCADE Technology Public
--- License Version 6.5 (the "License"). You may not use the content of this file
--- except in compliance with the License. Please obtain a copy of the License
--- at http://www.opencascade.org and read it completely before using this file.
---
--- The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
--- main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
---
--- The Original Code and all software distributed under the License is
--- distributed on an "AS IS" basis, without warranty of any kind, and the
--- Initial Developer hereby disclaims all such warranties, including without
--- limitation, any warranties of merchantability, fitness for a particular
--- purpose or non-infringement. Please see the License for the specific terms
--- and conditions governing the rights and limitations under the License.
-
--- Modified:   GG 23/11/00 Add Display(),Erase(),IsDisplayed() methods
-
-
-class Plane from V3d
-
-inherits
-
-       TShared
-       ---Purpose: Defines the services of Plane type objects. Only
-       --          the creation and editing of the functions is dealt
-       --          with here.
-       -- Warning: The representation of the clipping plane must be
-       --          calculated by the application by means of Graphic3d.
-       --          Editing of this representation must be coherent with
-       --          respect to the position of the plane.
-
-uses
-
-       View from V3d,
-       ClipPlane from Visual3d,
-       Structure from Graphic3d,
-       Parameter from Quantity,
-       Color from Quantity
-
-
-raises
-
-        BadValue from V3d
-
-is
-
-        --
-        -- The methods :
-        --
-
-       Create (A: Parameter = 0.0;
-               B: Parameter = 0.0;
-               C: Parameter = 1.0;
-               D: Parameter = 0.0
-       )  returns mutable Plane
-       ---Level : Public
-        ---Purpose: Creates a clipping plane using the equation :
-        --          <A>*X + <B>*Y + <C>*Z + <D> = 0.0
-       raises BadValue from V3d;
-       ---Purpose:  Warning! raises BadValue from V3d
-       --          if the norm of the plane is NULL.
-
-        --------------------------------------------------------
-        ---Category: Methods to modify the Attributs of the Plane
-        --------------------------------------------------------
-
-       SetPlane( me : mutable; A,B,C,D : Parameter)
-       ---Level : Public
-       ---Purpose: Modifies the plane equation.
-       raises BadValue from V3d
-       ---Purpose:  Warning! raises BadValue from V3d
-       --          if the norm of the plane is NULL.
-       --      If the norm of the plane is NULL.
-        is static;
-
-        Display(me: mutable; aView: View from V3d;
-                            aColor: Color from Quantity= Quantity_NOC_GRAY)
-       ---Level : Public
-       ---Purpose: Display the plane representation
-        --          in the choosen view.
-        is virtual;
-
-        Erase(me: mutable) is static;
-        ---Level: Public
-        ---Purpose: Erase the plane representation.
-
-        ---------------------------------------------------
-        ---Category: Inquire methods
-        ---------------------------------------------------
-
-       Plane( me ; A,B,C,D : out Parameter )  is static;
-       ---Level : Public
-       ---Purpose: Returns the parameters of the plane .
-
-       IsDisplayed( me ) returns Boolean from Standard is static;
-       ---Level : Public
-       ---Purpose: Returns TRUE when the plane representation is displayed
-
-        -----------------------------------------
-        ---Category: Private or Protected methods
-        -----------------------------------------
-
-        Plane( me) returns mutable ClipPlane from Visual3d is static private ;
-       ---Level : Internal
-        ---Purpose: Returns the associated plane from Visual3d.
-
-       Update( me : mutable ) is static private;
-       ---Level : Internal
-       ---Purpose: Updates the the plane representation.
-
-
-fields
-
-       MyPlane:        ClipPlane from Visual3d ;
-       MyGraphicStructure:     Structure from Graphic3d is protected;
-
-friends
-
-        SetPlaneOn from class View from V3d ( me : mutable ),
-        SetPlaneOn from class View from V3d
-                                ( me : mutable ; Plane : Plane from V3d ),
-        SetPlaneOff from class View from V3d ( me : mutable ),
-        SetPlaneOff from class View from V3d
-                                ( me : mutable ; Plane : Plane from V3d )
-
-end Plane;
old mode 100755 (executable)
new mode 100644 (file)
index b3ba033..aed96f9
@@ -1,6 +1,6 @@
 // Created by: GG
 // Copyright (c) 1991-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
-
-//-Version
-
-//-Design
-
-//-Warning
-
-//-References
-
-//-Language     C++ 2.1
-
-#include <V3d.hxx>
-#include <V3d_Plane.ixx>
-#include <V3d_BadValue.hxx>
-
+#include <V3d_Plane.hxx>
 #include <Graphic3d_Group.hxx>
-#include <Graphic3d_ArrayOfQuadrangles.hxx>
 #include <Graphic3d_AspectFillArea3d.hxx>
+#include <Graphic3d_ArrayOfQuadrangles.hxx>
 #include <gp_Pln.hxx>
 
-//-Constructors
-
-V3d_Plane::V3d_Plane(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D)
+IMPLEMENT_STANDARD_HANDLE(V3d_Plane, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(V3d_Plane, MMgt_TShared)
+
+// =======================================================================
+// function : V3d_Plane
+// purpose  :
+// =======================================================================
+V3d_Plane::V3d_Plane (const Standard_Real theA,
+                      const Standard_Real theB,
+                      const Standard_Real theC,
+                      const Standard_Real theD)
+: myGraphicStructure(),
+  myPlane (new Graphic3d_ClipPlane (gp_Pln (theA, theB, theC, theD)))
 {
-  V3d_BadValue_Raise_if( sqrt(A*A + B*B + C*C) <= 0., "V3d_Plane::V3d_Plane, bad plane coefficients");
-
-  MyPlane = new Visual3d_ClipPlane(A,B,C,D) ;
 }
 
-//-Methods, in order
-
-void V3d_Plane::SetPlane(const Standard_Real A, const Standard_Real B, const Standard_Real C, const Standard_Real D)
+// =======================================================================
+// function : V3d_Plane
+// purpose  :
+// =======================================================================
+void V3d_Plane::SetPlane (const Standard_Real theA,
+                          const Standard_Real theB,
+                          const Standard_Real theC,
+                          const Standard_Real theD)
 {
-  V3d_BadValue_Raise_if( sqrt(A*A + B*B + C*C) <= 0., "V3d_Plane::SetPlane, bad plane coefficients");
-
-  MyPlane->SetPlane(A,B,C,D) ;
-  if( IsDisplayed() )
+  myPlane->SetEquation (gp_Pln (theA, theB, theC, theD));
+  if (IsDisplayed())
+  {
     Update();
+  }
 }
 
-void V3d_Plane::Display(const Handle(V3d_View)& aView,
-                        const Quantity_Color& aColor)
+// =======================================================================
+// function : Display
+// purpose  :
+// =======================================================================
+void V3d_Plane::Display (const Handle(V3d_View)& theView,
+                         const Quantity_Color& theColor)
 {
-  Handle(V3d_Viewer) theViewer = aView->Viewer();
-  if (!MyGraphicStructure.IsNull())
-    MyGraphicStructure->Clear();
-
-  MyGraphicStructure = new Graphic3d_Structure(theViewer->Viewer());
-  Handle(Graphic3d_Group) group = new Graphic3d_Group(MyGraphicStructure);
-  Handle(Graphic3d_AspectFillArea3d) aspect = new Graphic3d_AspectFillArea3d();
-  Graphic3d_MaterialAspect plastic(Graphic3d_NOM_PLASTIC);
-  plastic.SetColor(aColor);
-  plastic.SetTransparency(0.5);
-  aView->SetTransparency(Standard_True);
-  aspect->SetFrontMaterial(plastic);
-  aspect->SetInteriorStyle (Aspect_IS_HATCH);
-  aspect->SetHatchStyle (Aspect_HS_GRID_DIAGONAL_WIDE);
-  MyGraphicStructure->SetPrimitivesAspect(aspect);
+  Handle(V3d_Viewer) aViewer = theView->Viewer();
+  if (!myGraphicStructure.IsNull())
+  {
+    myGraphicStructure->Clear();
+  }
 
-  const Standard_ShortReal size = (Standard_ShortReal)(0.5*theViewer->DefaultViewSize());
-  const Standard_ShortReal offset = size/5000.F;
+  myGraphicStructure = new Graphic3d_Structure (aViewer->Viewer());
+  Handle(Graphic3d_Group) aGroup = new Graphic3d_Group (myGraphicStructure);
+  Handle(Graphic3d_AspectFillArea3d) anAsp = new Graphic3d_AspectFillArea3d();
+  Graphic3d_MaterialAspect aPlastic (Graphic3d_NOM_PLASTIC);
+  aPlastic.SetColor (theColor);
+  aPlastic.SetTransparency (0.5);
+  theView->SetTransparency (Standard_True);
+  anAsp->SetFrontMaterial (aPlastic);
+  anAsp->SetInteriorStyle (Aspect_IS_HATCH);
+  anAsp->SetHatchStyle (Aspect_HS_GRID_DIAGONAL_WIDE);
+  myGraphicStructure->SetPrimitivesAspect (anAsp);
+
+  const Standard_ShortReal aSize = (Standard_ShortReal)(0.5*aViewer->DefaultViewSize());
+  const Standard_ShortReal anOffset = aSize/5000.0f;
 
   Handle(Graphic3d_ArrayOfQuadrangles) aPrims = new Graphic3d_ArrayOfQuadrangles(4);
-  aPrims->AddVertex(-size,-size,offset);
-  aPrims->AddVertex(-size, size,offset);
-  aPrims->AddVertex( size, size,offset);
-  aPrims->AddVertex( size,-size,offset);
-  group->AddPrimitiveArray(aPrims);
+  aPrims->AddVertex (-aSize,-aSize, anOffset);
+  aPrims->AddVertex (-aSize, aSize, anOffset);
+  aPrims->AddVertex ( aSize, aSize, anOffset);
+  aPrims->AddVertex ( aSize,-aSize, anOffset);
+  aGroup->AddPrimitiveArray(aPrims);
 
-  MyGraphicStructure->Display(0);
+  myGraphicStructure->Display(0);
   Update();
 }
 
+// =======================================================================
+// function : Erase
+// purpose  :
+// =======================================================================
 void V3d_Plane::Erase()
 {
-  if (!MyGraphicStructure.IsNull()) MyGraphicStructure->Erase();
-}
-
-void V3d_Plane::Plane(Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& D) const
-{
-  MyPlane->Plane(A,B,C,D) ;
+  if (!myGraphicStructure.IsNull())
+  {
+    myGraphicStructure->Erase();
+  }
 }
 
-Handle(Visual3d_ClipPlane) V3d_Plane::Plane()const
+// =======================================================================
+// function : Plane
+// purpose  :
+// =======================================================================
+void V3d_Plane::Plane (Standard_Real& theA, Standard_Real& theB, Standard_Real& theC, Standard_Real& theD) const
 {
-  return MyPlane;
+  const Graphic3d_ClipPlane::Equation& anEquation = myPlane->GetEquation();
+  theA = anEquation[0];
+  theB = anEquation[1];
+  theC = anEquation[2];
+  theD = anEquation[3];
 }
 
+// =======================================================================
+// function : IsDisplayed
+// purpose  :
+// =======================================================================
 Standard_Boolean V3d_Plane::IsDisplayed() const
 {
-  if( MyGraphicStructure.IsNull() ) return Standard_False;
-  return MyGraphicStructure->IsDisplayed();
+  if (myGraphicStructure.IsNull())
+  {
+    return Standard_False;
+  }
+
+  return myGraphicStructure->IsDisplayed();
 }
 
+// =======================================================================
+// function : Update
+// purpose  :
+// =======================================================================
 void V3d_Plane::Update()
 {
-  if( !MyGraphicStructure.IsNull() ) {
-    TColStd_Array2OfReal matrix(1,4,1,4);
-    Standard_Real A,B,C,D;
-    MyPlane->Plane(A,B,C,D) ;
-    gp_Pln plan(A,B,C,D);
-    gp_Trsf trsf;
-    trsf.SetTransformation(plan.Position());
-    trsf.Invert();
-    for (Standard_Integer i=1; i<=3; i++){
-      for (Standard_Integer j=1; j<=4; j++){
-        matrix.SetValue(i,j,trsf.Value(i,j));
+  if(!myGraphicStructure.IsNull())
+  {
+    TColStd_Array2OfReal aMatrix (1, 4, 1, 4);
+    Standard_Real theA, theB, theC, theD;
+    this->Plane(theA, theB, theC, theD);
+    gp_Pln aGeomPln (theA, theB, theC, theD);
+    gp_Trsf aTransform;
+    aTransform.SetTransformation (aGeomPln.Position());
+    aTransform.Invert();
+    for (Standard_Integer i = 1; i <= 3; i++)
+    {
+      for (Standard_Integer j = 1; j <= 4; j++)
+      {
+        aMatrix.SetValue (i, j, aTransform.Value (i,j));
       }
     }
-    matrix.SetValue(4,1,0.);
-    matrix.SetValue(4,2,0.);
-    matrix.SetValue(4,3,0.);
-    matrix.SetValue(4,4,1.);
-    MyGraphicStructure->SetTransform(matrix,Graphic3d_TOC_REPLACE);
+
+    aMatrix.SetValue (4,1,0.);
+    aMatrix.SetValue (4,2,0.);
+    aMatrix.SetValue (4,3,0.);
+    aMatrix.SetValue (4,4,1.);
+    myGraphicStructure->SetTransform (aMatrix, Graphic3d_TOC_REPLACE);
   }
 }
diff --git a/src/V3d/V3d_Plane.hxx b/src/V3d/V3d_Plane.hxx
new file mode 100644 (file)
index 0000000..d7bc09d
--- /dev/null
@@ -0,0 +1,105 @@
+// Created by: GG
+// Copyright (c) 1991-1999 Matra Datavision
+// Copyright (c) 1999-2013 OPEN CASCADE SAS
+//
+// The content of this file is subject to the Open CASCADE Technology Public
+// License Version 6.5 (the "License"). You may not use the content of this file
+// except in compliance with the License. Please obtain a copy of the License
+// at http://www.opencascade.org and read it completely before using this file.
+//
+// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
+// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+//
+// The Original Code and all software distributed under the License is
+// distributed on an "AS IS" basis, without warranty of any kind, and the
+// Initial Developer hereby disclaims all such warranties, including without
+// limitation, any warranties of merchantability, fitness for a particular
+// purpose or non-infringement. Please see the License for the specific terms
+// and conditions governing the rights and limitations under the License.
+
+#ifndef _V3d_Plane_H__
+#define _V3d_Plane_H__
+
+#include <Graphic3d_ClipPlane.hxx>
+#include <Graphic3d_Structure.hxx>
+#include <V3d_View.hxx>
+
+DEFINE_STANDARD_HANDLE (V3d_Plane, MMgt_TShared)
+
+//! Obsolete clip plane presentation class.
+//! Ported on new core of Graphic3d_ClipPlane approach.
+//! Please access Graphic3d_ClipPlane via ClipPlane() method
+//! to use it for standard clipping workflow.
+//! Example of use:
+//! @code
+//!
+//! Handle(V3d_Plane) aPlane (0, 1, 0, -20);
+//! Handle(V3d_View) aView;
+//! aView->AddClipPlane (aPlane->ClipPlane());
+//!
+//! aPlane->Display (aView);
+//! aPlane->SetPlane (0, 1, 0, -30);
+//! aView->RemoveClipPlane (aPlane->ClipPlane());
+//!
+//! @endcode
+//! Use interface of this class to modify plane equation synchronously
+//! with clipping equation.
+class V3d_Plane : public MMgt_TShared
+{
+public:
+
+  //! Creates a clipping plane from plane coefficients.
+  Standard_EXPORT V3d_Plane (const Quantity_Parameter theA = 0.0,
+                             const Quantity_Parameter theB = 0.0,
+                             const Quantity_Parameter theC = 1.0,
+                             const Quantity_Parameter theD = 0.0);
+
+  //! Change plane equation.
+  Standard_EXPORT void SetPlane (const Quantity_Parameter theA,
+                                 const Quantity_Parameter theB,
+                                 const Quantity_Parameter theC,
+                                 const Quantity_Parameter theD);
+
+  //! Display the plane representation in the choosen view.
+  Standard_EXPORT virtual void Display (const Handle(V3d_View)& theView,
+                                        const Quantity_Color& theColor = Quantity_NOC_GRAY);
+
+  //! Erase the plane representation.
+  Standard_EXPORT void Erase();
+
+  //! Returns the parameters of the plane.
+  Standard_EXPORT void Plane (Quantity_Parameter& theA,
+                              Quantity_Parameter& theB,
+                              Quantity_Parameter& theC,
+                              Quantity_Parameter& theD) const;
+
+  //! Returns TRUE when the plane representation is displayed <br>
+  Standard_EXPORT Standard_Boolean IsDisplayed() const;
+
+  //! Use this method to pass clipping plane implementation for
+  //! standard clipping workflow.
+  //! @return clipping plane implementation handle.
+  Standard_EXPORT const Handle(Graphic3d_ClipPlane)& ClipPlane() const
+  {
+    return myPlane;
+  }
+
+private:
+
+  //! Updates the the plane representation.
+  Standard_EXPORT void Update();
+
+protected:
+
+  Handle(Graphic3d_Structure) myGraphicStructure;
+
+private:
+
+  Handle(Graphic3d_ClipPlane) myPlane; //!< clip plane implementation.
+
+public:
+
+  DEFINE_STANDARD_RTTI(V3d_Plane)
+};
+
+#endif
index 66b6ab3..e9543ea 100755 (executable)
@@ -101,7 +101,6 @@ uses
         TypeOfBackfacingModel             from V3d,
         Viewer                            from V3d,
         Light                             from V3d,
-        Plane                             from V3d,
         View                              from Visual3d,
         ViewMapping                       from Visual3d,
         ViewOrientation                   from Visual3d,
@@ -136,8 +135,9 @@ uses
         FontAspect                        from Font,
         AsciiString                       from TCollection,
         ExtendedString                    from TCollection,
-        PrintAlgo                         from Aspect
-
+        PrintAlgo                         from Aspect,
+        ClipPlane_Handle                  from Graphic3d,
+        SetOfHClipPlane                   from Graphic3d
 raises
 
         BadValue from V3d, TypeMismatch from Standard,
@@ -392,7 +392,7 @@ is
         ---Level: Public
         ---Purpose: Deactivate all the Lights defined in this view.
 
-    IsActiveLight( me ; aLight: Light  from V3d )
+        IsActiveLight( me ; aLight: Light  from V3d )
         returns Boolean from Standard;
         ---Level: Public
         ---Purpose: Returns TRUE when the light is active in this view.
@@ -401,34 +401,6 @@ is
         ---Level: Public
         ---Purpose: Activate/Deactivate the transparency in this view.
 
-        SetPlaneOn( me : mutable ; MyPlane : Plane from V3d )
-        ---Level: Public
-        ---Purpose: Activates the clipping plane in this view.
-                raises BadValue from V3d ;
-        ---Purpose:      If No More Plane can be activated in MyView .
-
-        SetPlaneOn( me : mutable )
-        ---Level: Public
-        ---Purpose: Activate all the clipping planes defined in
-        --          this view.
-                raises BadValue from V3d;
-        ---Purpose:      If No More Plane can be activated in MyView .
-
-        SetPlaneOff( me : mutable ; MyPlane : Plane  from V3d );
-        ---Level: Public
-        ---Purpose: Desactivates the clipping plane defined
-        --          in this view.
-
-        SetPlaneOff( me : mutable );
-        ---Level: Public
-        ---Purpose: Deactivate all clipping planes defined
-        --          in this view.
-
-    IsActivePlane( me ; aPlane: Plane  from V3d )
-        returns Boolean from Standard;
-        ---Level: Public
-        ---Purpose: Returns TRUE when the plane is active in this view.
-        
         SetImmediateUpdate(me: mutable; theImmediateUpdate: Boolean from Standard)
         returns Boolean from Standard;
          ---Purpose: sets the immediate update mode and returns the previous one.
@@ -438,7 +410,7 @@ is
         --           Triedron methods
         ---------------------------------------------------
 
-    ZBufferTriedronSetup ( me      : mutable;
+        ZBufferTriedronSetup ( me      : mutable;
                            XColor  : NameOfColor from Quantity = Quantity_NOC_RED;
                            YColor  : NameOfColor from Quantity = Quantity_NOC_GREEN;
                            ZColor  : NameOfColor from Quantity = Quantity_NOC_BLUE1;
@@ -1223,27 +1195,6 @@ is
         ActiveLight(me) returns mutable Light from V3d;
         ---Level: Advanced
 
-        IfMorePlanes( me ) returns Boolean;
-        ---Level: Advanced
-        ---Purpose: Returns True if One clipping plane more can be
-        --          activated in this View.
-
-        InitActivePlanes(me: mutable);
-        ---Level: Advanced
-        ---Purpose: initializes an iteration on the active Planes.
-
-        MoreActivePlanes (me) returns Boolean from Standard;
-        ---Level: Advanced
-        ---Purpose: returns true if there are more active Plane(s) to return.
-
-        NextActivePlanes (me: mutable);
-        ---Level: Advanced
-        ---Purpose : Go to the next active Plane
-        --           (if there is not, ActivePlane will raise an exception)
-
-        ActivePlane(me) returns mutable Plane from V3d;
-        ---Level: Advanced
-
         Viewer ( me ) returns mutable Viewer from V3d;
         ---Level: Advanced
         ---Purpose: Returns the viewer in which the view has been created.
@@ -1604,13 +1555,36 @@ is
      ---Purpose: returns the current state of the gl lighting
      --          currently used in triedron displaying
 
+     AddClipPlane (me : mutable; thePlane : ClipPlane_Handle from Graphic3d) is virtual;
+     ---Purpose: Adds clip plane to the view. The composition of clip planes truncates the
+     -- r