1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-04 13:13:25 +03:00

0025129: Visualization - add interactive object for Points Cloud objects

New class AIS_PointCloud for displaying point sets.
Update Graphic3d_ArrayOfPoints, OpenGl_PrimitiveArray and OpenGl_VertexBuffer classes to be able to use normals for points.

Add Draw Harness command vpointcloud.
This commit is contained in:
kgv 2014-09-09 17:21:22 +04:00
parent f9823ea65a
commit 6635afb0c0
13 changed files with 813 additions and 47 deletions

View File

@ -368,6 +368,7 @@ is
---Category: General Objects ---Category: General Objects
class ConnectedInteractive; --signature 0 class ConnectedInteractive; --signature 0
class MultipleConnectedInteractive; --signature 1 class MultipleConnectedInteractive; --signature 1
imported PointCloud;
---Category: DIMENSIONS AND RELATIONS ---Category: DIMENSIONS AND RELATIONS

461
src/AIS/AIS_PointCloud.cxx Normal file
View File

@ -0,0 +1,461 @@
// Created on: 2014-08-13
// Created by: Maxim GLIBIN
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <AIS_PointCloud.hxx>
#include <AIS_Drawer.hxx>
#include <AIS_GraphicTool.hxx>
#include <Graphic3d_ArrayOfSegments.hxx>
#include <Graphic3d_AspectFillArea3d.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
#include <Graphic3d_Group.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_PointAspect.hxx>
#include <Prs3d_Presentation.hxx>
#include <Prs3d_Root.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <PrsMgr_ModedPresentation.hxx>
#include <PrsMgr_Presentations.hxx>
#include <Select3D_SensitiveBox.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_Selection.hxx>
#include <StdPrs_WFDeflectionRestrictedFace.hxx>
IMPLEMENT_STANDARD_HANDLE (AIS_PointCloud, AIS_InteractiveObject)
IMPLEMENT_STANDARD_RTTIEXT(AIS_PointCloud, AIS_InteractiveObject)
//==================================================
// Function: AIS_PointCloud
// Purpose : Constructor
//==================================================
AIS_PointCloud::AIS_PointCloud()
: mySelEntity (AIS_PointCloud::SE_BndBox)
{
SetDisplayMode (AIS_PointCloud::DM_Points);
SetHilightMode (AIS_PointCloud::DM_BndBox);
}
//=======================================================================
//function : GetPoints
//purpose :
//=======================================================================
const Handle(Graphic3d_ArrayOfPoints) AIS_PointCloud::GetPoints() const
{
return myPoints;
}
//=======================================================================
//function : GetBoundingBox
//purpose :
//=======================================================================
Bnd_Box AIS_PointCloud::GetBoundingBox() const
{
return myBndBox;
}
//! Auxiliary method
static inline Bnd_Box getBoundingBox (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
{
Bnd_Box aBndBox;
if (thePoints.IsNull())
{
return aBndBox;
}
const Standard_Integer aNbVertices = thePoints->VertexNumber();
for (Standard_Integer aVertIter = 1; aVertIter <= aNbVertices; ++aVertIter)
{
aBndBox.Add (thePoints->Vertice (aVertIter));
}
return aBndBox;
}
//=======================================================================
//function : SetPoints
//purpose :
//=======================================================================
void AIS_PointCloud::SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints)
{
myPoints = thePoints;
myBndBox = getBoundingBox (thePoints);
}
//=======================================================================
//function : SetPoints
//purpose :
//=======================================================================
void AIS_PointCloud::SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
const Handle(Quantity_HArray1OfColor)& theColors,
const Handle(TColgp_HArray1OfDir)& theNormals)
{
myPoints.Nullify();
myBndBox.SetVoid();
if (theCoords.IsNull())
{
return;
}
const Standard_Integer aNbPoints = theCoords->Length();
if ((!theNormals.IsNull() && theNormals->Length() != aNbPoints)
|| (!theColors.IsNull() && theColors->Length() != aNbPoints))
{
// invalid input
return;
}
const Standard_Boolean hasColors = !theColors.IsNull() && theColors->Length() == aNbPoints;
const Standard_Boolean hasNormals = !theNormals.IsNull() && theNormals->Length() == aNbPoints;
const Standard_Integer aDiffColors = hasColors ? (theColors->Lower() - theCoords->Lower()) : 0;
const Standard_Integer aDiffNormals = hasNormals ? (theNormals->Lower() - theCoords->Lower()) : 0;
myPoints = new Graphic3d_ArrayOfPoints (aNbPoints, hasColors, hasNormals);
for (Standard_Integer aPntIter = theCoords->Lower(); aPntIter <= theCoords->Upper(); ++aPntIter)
{
myPoints->AddVertex (theCoords->Value (aPntIter));
if (hasColors)
{
myPoints->SetVertexColor (myPoints->VertexNumber(),
theColors->Value (aPntIter + aDiffColors));
}
if (hasNormals)
{
myPoints->SetVertexNormal (myPoints->VertexNumber(),
theNormals->Value (aPntIter + aDiffNormals));
}
}
myBndBox = getBoundingBox (myPoints);
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void AIS_PointCloud::SetColor (const Quantity_NameOfColor theColor)
{
SetColor (Quantity_Color (theColor));
}
//=======================================================================
//function : SetColor
//purpose :
//=======================================================================
void AIS_PointCloud::SetColor (const Quantity_Color& theColor)
{
if (!myDrawer->HasPointAspect())
{
myDrawer->SetPointAspect (new Prs3d_PointAspect (Aspect_TOM_POINT, theColor, 1.0));
*myDrawer->PointAspect()->Aspect() = *myDrawer->Link()->PointAspect()->Aspect();
}
if (!myDrawer->HasShadingAspect())
{
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
*myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
}
// Override color
myDrawer->ShadingAspect()->SetColor (theColor);
myDrawer->PointAspect() ->SetColor (theColor);
hasOwnColor = Standard_True;
myOwnColor = theColor;
const PrsMgr_Presentations& aPrsList = Presentations();
Handle(Graphic3d_AspectMarker3d) aPointAspect = myDrawer->PointAspect()->Aspect();
Handle(Graphic3d_AspectFillArea3d) anAreaAspect = myDrawer->ShadingAspect()->Aspect();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
// Set aspects for presentation
aPrs->SetPrimitivesAspect (aPointAspect);
aPrs->SetPrimitivesAspect (anAreaAspect);
// Go through all groups to change color for all primitives
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
{
aGroup->SetGroupPrimitivesAspect (aPointAspect);
}
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetGroupPrimitivesAspect (anAreaAspect);
}
}
}
}
//=======================================================================
//function : UnsetColor
//purpose :
//=======================================================================
void AIS_PointCloud::UnsetColor()
{
if (!HasColor())
{
return;
}
hasOwnColor = Standard_False;
if (!HasWidth())
{
myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
}
else
{
Quantity_Color aColor;
Aspect_TypeOfMarker aType = Aspect_TOM_POINT;
Standard_Real aScale = 1.0;
myDrawer->Link()->PointAspect()->Aspect()->Values (aColor, aType, aScale);
myDrawer->PointAspect()->SetColor (aColor);
}
if (HasMaterial()
|| IsTransparent())
{
Graphic3d_MaterialAspect aMat = AIS_GraphicTool::GetMaterial (HasMaterial() ? myDrawer : myDrawer->Link());
if (HasMaterial())
{
Quantity_Color aColor = myDrawer->Link()->ShadingAspect()->Color (myCurrentFacingModel);
aMat.SetColor (aColor);
}
if (IsTransparent())
{
Standard_Real aTransp = myDrawer->ShadingAspect()->Transparency (myCurrentFacingModel);
aMat.SetTransparency (aTransp);
}
myDrawer->ShadingAspect()->SetMaterial (aMat, myCurrentFacingModel);
}
else
{
myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
}
myDrawer->SetPointAspect (Handle(Prs3d_PointAspect)());
// modify shading presentation without re-computation
const PrsMgr_Presentations& aPrsList = Presentations();
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->Link()->ShadingAspect()->Aspect();
Handle(Graphic3d_AspectMarker3d) aMarkerAsp = myDrawer->Link()->PointAspect()->Aspect();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
aPrs->SetPrimitivesAspect (anAreaAsp);
aPrs->SetPrimitivesAspect (aMarkerAsp);
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
// Check if aspect of given type is set for the group,
// because setting aspect for group with no already set aspect
// can lead to loss of presentation data
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetGroupPrimitivesAspect (anAreaAsp);
}
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_MARKER))
{
aGroup->SetGroupPrimitivesAspect (aMarkerAsp);
}
}
}
}
//=======================================================================
//function : SetMaterial
//purpose :
//=======================================================================
void AIS_PointCloud::SetMaterial (const Graphic3d_NameOfMaterial theMatName)
{
SetMaterial (Graphic3d_MaterialAspect (theMatName));
}
//=======================================================================
//function : SetMaterial
//purpose :
//=======================================================================
void AIS_PointCloud::SetMaterial (const Graphic3d_MaterialAspect& theMat)
{
if (!myDrawer->HasShadingAspect())
{
myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
*myDrawer->ShadingAspect()->Aspect() = *myDrawer->Link()->ShadingAspect()->Aspect();
}
hasOwnMaterial = Standard_True;
myDrawer->ShadingAspect()->SetMaterial (theMat, myCurrentFacingModel);
if (HasColor())
{
myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
}
myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
// modify shading presentation without re-computation
const PrsMgr_Presentations& aPrsList = Presentations();
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
aPrs->SetPrimitivesAspect (anAreaAsp);
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetGroupPrimitivesAspect (anAreaAsp);
}
}
}
}
//=======================================================================
//function : UnsetMaterial
//purpose :
//=======================================================================
void AIS_PointCloud::UnsetMaterial()
{
if (!HasMaterial())
{
return;
}
if (HasColor()
|| IsTransparent())
{
myDrawer->ShadingAspect()->SetMaterial (myDrawer->Link()->ShadingAspect()->Material (myCurrentFacingModel),
myCurrentFacingModel);
if (HasColor())
{
myDrawer->ShadingAspect()->SetColor (myOwnColor, myCurrentFacingModel);
myDrawer->ShadingAspect()->SetTransparency (myTransparency, myCurrentFacingModel);
}
}
else
{
myDrawer->SetShadingAspect (Handle(Prs3d_ShadingAspect)());
}
hasOwnMaterial = Standard_False;
// modify shading presentation without re-computation
const PrsMgr_Presentations& aPrsList = Presentations();
Handle(Graphic3d_AspectFillArea3d) anAreaAsp = myDrawer->ShadingAspect()->Aspect();
for (Standard_Integer aPrsIt = 1; aPrsIt <= aPrsList.Length(); ++aPrsIt)
{
const PrsMgr_ModedPresentation& aPrsModed = aPrsList.Value (aPrsIt);
if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
{
continue;
}
const Handle(Prs3d_Presentation)& aPrs = aPrsModed.Presentation()->Presentation();
aPrs->SetPrimitivesAspect (anAreaAsp);
for (Graphic3d_SequenceOfGroup::Iterator aGroupIt (aPrs->Groups()); aGroupIt.More(); aGroupIt.Next())
{
const Handle(Graphic3d_Group)& aGroup = aGroupIt.Value();
if (aGroup->IsGroupPrimitivesAspectSet (Graphic3d_ASPECT_FILL_AREA))
{
aGroup->SetGroupPrimitivesAspect (anAreaAsp);
}
}
}
}
//=======================================================================
//function : Compute
//purpose :
//=======================================================================
void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePrsMgr*/,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode)
{
thePrs->Clear();
switch (theMode)
{
case AIS_PointCloud::DM_Points:
{
const Handle(Graphic3d_ArrayOfPoints) aPoints = GetPoints();
if (aPoints.IsNull())
{
return;
}
Handle(Graphic3d_AspectMarker3d) aMarkerAspect = myDrawer->PointAspect()->Aspect();
if (!myDrawer->HasPointAspect())
{
aMarkerAspect->SetType (Aspect_TOM_POINT);
}
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
aGroup->SetGroupPrimitivesAspect (aMarkerAspect);
aGroup->AddPrimitiveArray (aPoints);
break;
}
case AIS_PointCloud::DM_BndBox:
{
Bnd_Box aBndBox = GetBoundingBox();
if (aBndBox.IsVoid())
{
return;
}
StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, aBndBox, myDrawer);
break;
}
}
}
//=======================================================================
//function : ComputeSelection
//purpose :
//=======================================================================
void AIS_PointCloud::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer /*theMode*/)
{
switch (mySelEntity)
{
case AIS_PointCloud::SE_DISABLED:
{
return;
}
case AIS_PointCloud::SE_BndBox:
{
Bnd_Box aBndBox = GetBoundingBox();
if (aBndBox.IsVoid())
{
return;
}
Handle(SelectMgr_EntityOwner) anOwner = new SelectMgr_EntityOwner (this);
Handle(Select3D_SensitiveBox) aSensBox = new Select3D_SensitiveBox (anOwner, aBndBox);
theSelection->Add (aSensBox);
return;
}
}
}

126
src/AIS/AIS_PointCloud.hxx Normal file
View File

@ -0,0 +1,126 @@
// Created on: 2014-08-13
// Created by: Maxim GLIBIN
// Copyright (c) 2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _AIS_PointCloud_HeaderFile
#define _AIS_PointCloud_HeaderFile
#include <AIS.hxx>
#include <AIS_InteractiveObject.hxx>
#include <Bnd_Box.hxx>
#include <Graphic3d_ArrayOfPoints.hxx>
#include <Quantity_HArray1OfColor.hxx>
#include <Standard.hxx>
#include <Standard_DefineHandle.hxx>
#include <Standard_Macro.hxx>
#include <TColgp_HArray1OfDir.hxx>
#include <TColgp_HArray1OfPnt.hxx>
DEFINE_STANDARD_HANDLE(AIS_PointCloud, AIS_InteractiveObject)
//! Interactive object for set of points.
//! Selection services are not provided by this class.
class AIS_PointCloud : public AIS_InteractiveObject
{
public:
//! Display modes supported by this Point Cloud object
enum DisplayMode
{
DM_Points = 0, //!< display as normal points, default presentation
DM_BndBox = 2 //!< display as bounding box, default for highlighting
};
//! Entity to use for selection.
//! Default - select by bounding box.
enum SelectionEntity
{
SE_DISABLED = 0, //!< do not create selection entity - object will be unselectable from 3D viewer, but can be highlighted from application
SE_BndBox = 2 //!< create bounding box selection entity
};
public:
//! Empty constructor
Standard_EXPORT AIS_PointCloud();
//! Sets the points from array of points.
//! Method will not copy the input data - array will be stored as handle.
//! @param thePoints [in] the array of points
Standard_EXPORT virtual void SetPoints (const Handle(Graphic3d_ArrayOfPoints)& thePoints);
//! Sets the points with optional colors.
//! The input data will be copied into internal buffer.
//! @param theCoords [in] the array of coordinates
//! @param theColors [in] optional array of colors
//! @param theNormals [in] optional array of normals
Standard_EXPORT virtual void SetPoints (const Handle(TColgp_HArray1OfPnt)& theCoords,
const Handle(Quantity_HArray1OfColor)& theColors = NULL,
const Handle(TColgp_HArray1OfDir)& theNormals = NULL);
public:
//! Get the points array.
//! Method might be overridden to fill in points array dynamically from application data structures.
//! @return the array of points
Standard_EXPORT virtual const Handle(Graphic3d_ArrayOfPoints) GetPoints() const;
//! Get bounding box for presentation.
Standard_EXPORT virtual Bnd_Box GetBoundingBox() const;
public:
//! Setup custom color. Affects presentation only when no per-point color attribute has been assigned.
Standard_EXPORT virtual void SetColor (const Quantity_NameOfColor theColor);
//! Setup custom color. Affects presentation only when no per-point color attribute has been assigned.
Standard_EXPORT virtual void SetColor (const Quantity_Color& theColor);
//! Restore default color.
Standard_EXPORT virtual void UnsetColor();
//! Setup custom material. Affects presentation only when normals are defined.
Standard_EXPORT virtual void SetMaterial (const Graphic3d_NameOfMaterial theMatName);
//! Setup custom material. Affects presentation only when normals are defined.
Standard_EXPORT virtual void SetMaterial (const Graphic3d_MaterialAspect& theMat);
//! Restore default material.
Standard_EXPORT virtual void UnsetMaterial();
protected:
//! Prepare presentation for this object.
Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
const Handle(Prs3d_Presentation)& thePrs,
const Standard_Integer theMode);
//! Prepare selection for this object.
Standard_EXPORT virtual void ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode);
private:
Handle(Graphic3d_ArrayOfPoints) myPoints; //!< points array for presentation
Bnd_Box myBndBox; //!< bounding box for presentation
SelectionEntity mySelEntity; //!< selection entity
public:
DEFINE_STANDARD_RTTI(AIS_PointCloud)
};
#endif // _AIS_PointCloud_HeaderFile

View File

@ -98,31 +98,7 @@ void AIS_Shape::DisplayBox(const Handle(Prs3d_Presentation)& aPrs,
const Bnd_Box& B, const Bnd_Box& B,
const Handle(Prs3d_Drawer)& aDrawer) const Handle(Prs3d_Drawer)& aDrawer)
{ {
static const Standard_Integer Indx[][3] = return StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, B, aDrawer);
{ { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 },
{ 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 },
{ 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 },
{ 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } };
if ( B.IsVoid() )
return; // nothing to show
Standard_Real X[2],Y[2],Z[2];
B.Get(X[0], Y[0], Z[0], X[1], Y[1], Z[1]);
Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(aPrs);
Quantity_Color Q;
Aspect_TypeOfLine A;
Standard_Real W;
aDrawer->LineAspect()->Aspect()->Values(Q,A,W);
G->SetGroupPrimitivesAspect(new Graphic3d_AspectLine3d(Q,Aspect_TOL_DOTDASH,W));
Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16);
Standard_Integer i(0);
for(;i<16;i++)
aPolyline->AddVertex(X[Indx[i][0]],Y[Indx[i][1]],Z[Indx[i][2]]);
G->AddPrimitiveArray(aPolyline);
} }
static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode) static Standard_Boolean IsInList(const TColStd_ListOfInteger& LL, const Standard_Integer aMode)
@ -255,7 +231,7 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
{ {
// bounding box // bounding box
if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
else DisplayBox(aPrs,BoundingBox(),myDrawer); else StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, BoundingBox(), myDrawer);
} }
} // end switch } // end switch
aPrs->ReCompute(); // for hidden line recomputation if necessary... aPrs->ReCompute(); // for hidden line recomputation if necessary...

View File

@ -325,7 +325,7 @@ void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*t
} }
else else
{ {
AIS_Shape::DisplayBox (thePrs, BoundingBox(), myDrawer); StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, BoundingBox(), myDrawer);
} }
break; break;
} }

View File

@ -21,3 +21,5 @@ AIS_DiameterDimension.hxx
AIS_DiameterDimension.cxx AIS_DiameterDimension.cxx
AIS_RadiusDimension.hxx AIS_RadiusDimension.hxx
AIS_RadiusDimension.cxx AIS_RadiusDimension.cxx
AIS_PointCloud.hxx
AIS_PointCloud.cxx

View File

@ -18,11 +18,13 @@ is
-- constructor -- constructor
Create (maxVertexs: Integer from Standard; Create (maxVertexs: Integer from Standard;
hasVColors: Boolean from Standard = Standard_False) hasVColors: Boolean from Standard = Standard_False;
returns mutable ArrayOfPoints from Graphic3d; hasVNormals: Boolean from Standard = Standard_False)
returns ArrayOfPoints from Graphic3d;
---Purpose: Creates an array of points, ---Purpose: Creates an array of points,
-- a single pixel point is drawn at each vertex. -- a single pixel point is drawn at each vertex.
-- The array must be filled using the AddVertex(Point) method. -- The array must be filled using the AddVertex(Point) method.
-- When <hasVColors> is TRUE , you must use only AddVertex(Point,Color) method. -- When <hasVColors> is TRUE , you must use only AddVertex(Point,Color) method.
-- When <hasVNormals> is TRUE , you must use only AddVertex(Point,Normal) method.
end; end;

View File

@ -14,7 +14,8 @@
#include <Graphic3d_ArrayOfPoints.ixx> #include <Graphic3d_ArrayOfPoints.ixx>
Graphic3d_ArrayOfPoints :: Graphic3d_ArrayOfPoints (const Standard_Integer maxVertexs, Graphic3d_ArrayOfPoints::Graphic3d_ArrayOfPoints (const Standard_Integer theMaxVertexs,
const Standard_Boolean hasVColors) const Standard_Boolean theHasVColors,
: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, maxVertexs, 0, 0, Standard_False, hasVColors, Standard_False, Standard_False, Standard_False) const Standard_Boolean theHasVNormals)
: Graphic3d_ArrayOfPrimitives (Graphic3d_TOPA_POINTS, theMaxVertexs, 0, 0, theHasVNormals, theHasVColors, Standard_False, Standard_False)
{} {}

View File

@ -231,14 +231,6 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
pvc = NULL; pvc = NULL;
} }
// Sometimes the GL_LIGHTING mode is activated here
// without glEnable(GL_LIGHTING) call for an unknown reason, so it is necessary
// to call glEnable(GL_LIGHTING) to synchronize Light On/Off mechanism*
if (theLightingModel == 0 || myDrawMode <= GL_LINE_STRIP)
glDisable (GL_LIGHTING);
else
glEnable (GL_LIGHTING);
if (!toDrawVbo()) if (!toDrawVbo())
{ {
if (myPArray->vertices != NULL) if (myPArray->vertices != NULL)
@ -246,10 +238,15 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices glVertexPointer (3, GL_FLOAT, 0, myPArray->vertices); // array of vertices
glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_VERTEX_ARRAY);
} }
if (myPArray->vnormals != NULL) if (myPArray->vnormals != NULL && theLightingModel != 0)
{ {
glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals glNormalPointer (GL_FLOAT, 0, myPArray->vnormals); // array of normals
glEnableClientState (GL_NORMAL_ARRAY); glEnableClientState (GL_NORMAL_ARRAY);
glEnable (GL_LIGHTING);
}
else
{
glDisable (GL_LIGHTING);
} }
if (myPArray->vtexels != NULL) if (myPArray->vtexels != NULL)
{ {
@ -269,9 +266,14 @@ void OpenGl_PrimitiveArray::DrawArray (Tint theLightingModel,
{ {
// Bindings concrete pointer in accordance with VBO buffer // Bindings concrete pointer in accordance with VBO buffer
myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY); myVbos[VBOVertices]->BindFixed (aGlContext, GL_VERTEX_ARRAY);
if (!myVbos[VBOVnormals].IsNull()) if (!myVbos[VBOVnormals].IsNull() && theLightingModel != 0)
{ {
myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY); myVbos[VBOVnormals]->BindFixed (aGlContext, GL_NORMAL_ARRAY);
glEnable (GL_LIGHTING);
}
else
{
glDisable (GL_LIGHTING);
} }
if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0) if (!myVbos[VBOVtexels].IsNull() && (theWorkspace->NamedStatus & OPENGL_NS_FORBIDSETTEX) == 0)
{ {

View File

@ -24,13 +24,13 @@ inherits Root from Prs3d
-- a deflection on them. -- a deflection on them.
uses uses
Box from Bnd,
HSurface from BRepAdaptor, HSurface from BRepAdaptor,
Presentation from Prs3d, Presentation from Prs3d,
Drawer from Prs3d, Drawer from Prs3d,
Length from Quantity, Length from Quantity,
NListOfSequenceOfPnt from Prs3d NListOfSequenceOfPnt from Prs3d
is is
Add(myclass; aPresentation: Presentation from Prs3d; Add(myclass; aPresentation: Presentation from Prs3d;
aFace : HSurface from BRepAdaptor; aFace : HSurface from BRepAdaptor;
@ -109,6 +109,12 @@ is
-- Curves give a sequence of face curves, it is used if the PrimitiveArray -- Curves give a sequence of face curves, it is used if the PrimitiveArray
-- visualization approach is activated (it is activated by default). -- visualization approach is activated (it is activated by default).
AddBox (myclass;
thePrs : Presentation from Prs3d;
theBndBox : Box from Bnd;
theDrawer : Drawer from Prs3d);
---Purpose: Adds box as polyline to the presentation object
Match(myclass; X,Y,Z : Length from Quantity; Match(myclass; X,Y,Z : Length from Quantity;
aDistance: Length from Quantity; aDistance: Length from Quantity;
aFace : HSurface from BRepAdaptor; aFace : HSurface from BRepAdaptor;

View File

@ -17,6 +17,8 @@
#include <StdPrs_WFDeflectionRestrictedFace.ixx> #include <StdPrs_WFDeflectionRestrictedFace.ixx>
#include <Hatch_Hatcher.hxx> #include <Hatch_Hatcher.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_Group.hxx> #include <Graphic3d_Group.hxx>
#include <gp_Pnt.hxx> #include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx> #include <gp_Pnt2d.hxx>
@ -623,3 +625,46 @@ Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
aDrawer->UIsoAspect()->Number(), aDrawer->UIsoAspect()->Number(),
aDrawer->VIsoAspect()->Number()); aDrawer->VIsoAspect()->Number());
} }
namespace
{
static const Standard_Integer THE_INDICES[][3] =
{ { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 },
{ 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 },
{ 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 },
{ 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } };
}
//=======================================================================
//function : AddBox
//purpose :
//=======================================================================
void StdPrs_WFDeflectionRestrictedFace::AddBox (const Handle(Prs3d_Presentation)& thePrs,
const Bnd_Box& theBndBox,
const Handle(Prs3d_Drawer)& theDrawer)
{
if (theBndBox.IsVoid())
{
return;
}
Standard_Real X[2], Y[2], Z[2];
theBndBox.Get (X[0], Y[0], Z[0], X[1], Y[1], Z[1]);
Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs);
Quantity_Color aColor;
Aspect_TypeOfLine aDummyLineType;
Standard_Real aWidth = 1.0;
theDrawer->LineAspect()->Aspect()->Values (aColor, aDummyLineType, aWidth);
aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (aColor, Aspect_TOL_DOTDASH, aWidth));
Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16);
for(Standard_Integer aVertIter = 0; aVertIter < 16; ++aVertIter)
{
aPolyline->AddVertex (X[THE_INDICES[aVertIter][0]],
Y[THE_INDICES[aVertIter][1]],
Z[THE_INDICES[aVertIter][2]]);
}
aGroup->AddPrimitiveArray (aPolyline);
}

View File

@ -39,6 +39,7 @@
#include <AIS_Shape.hxx> #include <AIS_Shape.hxx>
#include <AIS_DisplayMode.hxx> #include <AIS_DisplayMode.hxx>
#include <AIS_PointCloud.hxx>
#include <TColStd_MapOfInteger.hxx> #include <TColStd_MapOfInteger.hxx>
#include <AIS_MapOfInteractive.hxx> #include <AIS_MapOfInteractive.hxx>
#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx> #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
@ -5028,6 +5029,140 @@ static int VFont (Draw_Interpretor& theDI,
return 0; return 0;
} }
//=======================================================================
//function : VPointCloud
//purpose : Create interactive object for arbitary set of points.
//=======================================================================
static Standard_Integer VPointCloud (Draw_Interpretor& theDI,
Standard_Integer theArgNum,
const char** theArgs)
{
Handle(AIS_InteractiveContext) anAISContext = ViewerTest::GetAISContext();
if (theArgNum < 3)
{
std::cout << "Error: wrong number of arguments! See usage:\n";
theDI.PrintHelp (theArgs[0]);
return 1;
}
else if (anAISContext.IsNull())
{
std::cerr << "Error: no active view!\n";
return 1;
}
Standard_Integer anArgIter = 1;
Standard_CString aName = theArgs[anArgIter++];
Standard_CString aShapeName = theArgs[anArgIter++];
TopoDS_Shape aShape = DBRep::Get (aShapeName);
if (aShape.IsNull())
{
std::cout << "Error: no shape with name '" << aShapeName << "' found\n";
return 1;
}
// parse arguments
Standard_Boolean toRandColors = Standard_False;
Standard_Boolean hasNormals = Standard_True;
for (; anArgIter < theArgNum; ++anArgIter)
{
Standard_CString anArg = theArgs[anArgIter];
TCollection_AsciiString aFlag (anArg);
aFlag.LowerCase();
if (aFlag == "-randcolors"
|| aFlag == "-randcolor")
{
toRandColors = Standard_True;
}
else if (aFlag == "-normals"
|| aFlag == "-normal")
{
hasNormals = Standard_True;
}
else if (aFlag == "-nonormals"
|| aFlag == "-nonormal")
{
hasNormals = Standard_False;
}
else
{
std::cout << "Error: unknown argument '" << anArg << "'\n";
return 1;
}
}
// calculate number of points
TopLoc_Location aLocation;
Standard_Integer aNbPoints = 0;
for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation);
if (!aTriangulation.IsNull())
{
aNbPoints += aTriangulation->NbNodes();
}
}
if (aNbPoints < 3)
{
std::cout << "Error: shape should be triangulated!\n";
return 1;
}
VDisplayAISObject (aName, NULL);
Handle(Graphic3d_ArrayOfPoints) anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current());
Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation);
if (aTriangulation.IsNull())
{
continue;
}
const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
const gp_Trsf& aTrsf = aLocation.Transformation();
// extract normals from nodes
TColgp_Array1OfDir aNormals (aNodes.Lower(), hasNormals ? aNodes.Upper() : aNodes.Lower());
if (hasNormals)
{
Poly_Connect aPolyConnect (aTriangulation);
StdPrs_ToolShadedShape::Normal (aFace, aPolyConnect, aNormals);
}
for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
{
gp_Pnt aPoint = aNodes (aNodeIter);
if (!aLocation.IsIdentity())
{
aPoint.Transform (aTrsf);
aNormals (aNodeIter).Transform (aTrsf);
}
// add vertex into array of points
const Standard_Integer anIndexOfPoint = anArrayPoints->AddVertex (aPoint);
if (toRandColors)
{
Quantity_Color aColor (360.0 * Standard_Real(anIndexOfPoint) / Standard_Real(aNbPoints),
1.0, 0.5, Quantity_TOC_HLS);
anArrayPoints->SetVertexColor (anIndexOfPoint, aColor);
}
if (hasNormals)
{
anArrayPoints->SetVertexNormal (anIndexOfPoint, aNormals (aNodeIter));
}
}
}
// set array of points in point cloud object
Handle(AIS_PointCloud) aPointCloud = new AIS_PointCloud();
aPointCloud->SetPoints (anArrayPoints);
VDisplayAISObject (aName, aPointCloud);
return 0;
}
//======================================================================= //=======================================================================
//function : ObjectsCommands //function : ObjectsCommands
//purpose : //purpose :
@ -5185,4 +5320,13 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
"vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]" "vfont [add pathToFont [fontName] [regular,bold,italic,bolditalic=undefined]]"
"\n\t\t: [find fontName [regular,bold,italic,bolditalic=undefined]]", "\n\t\t: [find fontName [regular,bold,italic,bolditalic=undefined]]",
__FILE__, VFont, group); __FILE__, VFont, group);
theCommands.Add ("vpointcloud",
"vpointcloud name shapename [-randColor] [-normals] [-noNormals]"
"\n\t\t: Create an interactive object for arbitary set of points"
"\n\t\t: from triangulated shape."
"\n\t\t: -randColor - generate random color per point"
"\n\t\t: -normals - generate normal per point (default)"
"\n\t\t: -noNormals - do not generate normal per point",
__FILE__, VPointCloud, group);
} }