1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +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.
Add test case v3d/point_cloud/sphere.

Move protected method AIS_Shape::DisplayBox() to public function StdPrs_WFDeflectionRestrictedFace::AddBox().

Small correction of grids.list for v3d tests
This commit is contained in:
apl 2014-09-25 13:54:33 +04:00 committed by bugmaster
parent a9b30f0acb
commit d33222c108
14 changed files with 917 additions and 44 deletions

View File

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

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

@ -0,0 +1,451 @@
// 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_AspectFillArea3d.hxx>
#include <Graphic3d_AspectMarker3d.hxx>
#include <Graphic3d_Group.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()
{
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)
{
AIS_InteractiveObject::SetColor(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);
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);
if (aPrsModed.Mode() != AIS_PointCloud::DM_Points)
{
continue;
}
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;
}
AIS_InteractiveObject::UnsetColor();
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*/)
{
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);
}

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

@ -0,0 +1,128 @@
// 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.
//! The presentation supports two display modes:
//! - Points.
//! - Bounding box for highlighting.
//! Presentation provides selection by bouding box.
//! Selection and consequently highlighting can disabled by
//! setting default selection mode to -1. There will be no way
//! to select object from interactive view. Any calls to
//! AIS_InteractiveContext::AddOrRemoveSelected should be also prohibited,
//! to avoid programmatic highlighting (workaround is setting non-supported
//! hilight mode, e.g. 100);
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
};
public:
//! 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.
//! The input arrays should have equal length, otherwise
//! the presentation will not be computed and displayed.
//! @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
public:
DEFINE_STANDARD_RTTI(AIS_PointCloud)
};
#endif // _AIS_PointCloud_HeaderFile

View File

@ -290,11 +290,7 @@ uses
aProjector : Projector from Prs3d;
aPresentation : Presentation from Prs3d;
ashape : Shape from TopoDS) is static private;
DisplayBox(myclass; aPrs : Presentation from Prs3d;
aBox : Box from Bnd;
aDrawer : Drawer from Prs3d) is protected;
setColor (me;
theDrawer : Drawer from AIS;
theColor : Color from Quantity)

View File

@ -77,37 +77,6 @@
static Standard_Boolean myFirstCompute;
void AIS_Shape::DisplayBox(const Handle(Prs3d_Presentation)& aPrs,
const Bnd_Box& B,
const Handle(Prs3d_Drawer)& aDrawer)
{
static const Standard_Integer Indx[][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 } };
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)
{
TColStd_ListIteratorOfListOfInteger It(LL);
@ -238,7 +207,7 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat
{
// bounding box
if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
else DisplayBox(aPrs,BoundingBox(),myDrawer);
else StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, BoundingBox(), myDrawer);
}
} // end switch
aPrs->ReCompute(); // for hidden line recomputation if necessary...

View File

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

View File

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

View File

@ -19,11 +19,13 @@ is
-- constructor
Create (maxVertexs: Integer from Standard;
hasVColors: Boolean from Standard = Standard_False)
hasVColors: Boolean from Standard = Standard_False;
hasVNormals: Boolean from Standard = Standard_False)
returns ArrayOfPoints from Graphic3d;
---Purpose: Creates an array of points,
-- a single pixel point is drawn at each vertex.
-- The array must be filled using the AddVertex(Point) 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;

View File

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

View File

@ -29,13 +29,13 @@ inherits Root from Prs3d
-- The presentation includes the restriction curves.
uses
Box from Bnd,
HSurface from BRepAdaptor,
Presentation from Prs3d,
Drawer from Prs3d,
Length from Quantity,
NListOfSequenceOfPnt from Prs3d
is
Add(myclass; aPresentation: Presentation from Prs3d;
aFace : HSurface from BRepAdaptor;
@ -113,7 +113,13 @@ is
-- as a geometric surface.
-- Curves give a sequence of face curves, it is used if the PrimitiveArray
-- 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;
aDistance: Length from Quantity;
aFace : HSurface from BRepAdaptor;

View File

@ -17,6 +17,8 @@
#include <StdPrs_WFDeflectionRestrictedFace.ixx>
#include <Hatch_Hatcher.hxx>
#include <Graphic3d_ArrayOfPolylines.hxx>
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_Group.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
@ -625,3 +627,46 @@ Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso
aDrawer->UIsoAspect()->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

@ -33,6 +33,7 @@
#include <AIS_Shape.hxx>
#include <AIS_DisplayMode.hxx>
#include <AIS_PointCloud.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <AIS_MapOfInteractive.hxx>
#include <ViewerTest_AutoUpdater.hxx>
@ -5366,6 +5367,228 @@ static int VVertexMode (Draw_Interpretor& theDI,
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 (anAISContext.IsNull())
{
std::cerr << "Error: no active view!\n";
return 1;
}
// command to execute
enum Command
{
CloudForShape, // generate point cloud for shape
CloudSphere, // generate point cloud for generic sphere
Unknow
};
// count number of non-optional command arguments
Command aCmd = Unknow;
Standard_Integer aCmdArgs = 0;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
{
Standard_CString anArg = theArgs[anArgIter];
TCollection_AsciiString aFlag (anArg);
aFlag.LowerCase();
if (aFlag.IsRealValue() || aFlag.Search ("-") != 1)
{
aCmdArgs++;
}
}
switch (aCmdArgs)
{
case 2 : aCmd = CloudForShape; break;
case 7 : aCmd = CloudSphere; break;
default :
std::cout << "Error: wrong number of arguments! See usage:\n";
theDI.PrintHelp (theArgs[0]);
return 1;
}
// parse options
Standard_Boolean toRandColors = Standard_False;
Standard_Boolean hasNormals = Standard_True;
Standard_Boolean isSetArgNorm = Standard_False;
for (Standard_Integer anArgIter = 1; anArgIter < theArgNum; ++anArgIter)
{
Standard_CString anArg = theArgs[anArgIter];
TCollection_AsciiString aFlag (anArg);
aFlag.LowerCase();
if (aFlag == "-randcolors"
|| aFlag == "-randcolor")
{
if (isSetArgNorm && hasNormals)
{
std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
return 1;
}
toRandColors = Standard_True;
hasNormals = Standard_False;
}
else if (aFlag == "-normals"
|| aFlag == "-normal")
{
if (toRandColors)
{
std::cout << "Error: wrong syntax - normals can not be enabled with colors at the same time\n";
return 1;
}
isSetArgNorm = Standard_True;
hasNormals = Standard_True;
}
else if (aFlag == "-nonormals"
|| aFlag == "-nonormal")
{
isSetArgNorm = Standard_True;
hasNormals = Standard_False;
}
}
Standard_CString aName = theArgs[1];
// generate arbitrary set of points
Handle(Graphic3d_ArrayOfPoints) anArrayPoints;
if (aCmd == CloudForShape)
{
Standard_CString aShapeName = theArgs[2];
TopoDS_Shape aShape = DBRep::Get (aShapeName);
if (aShape.IsNull())
{
std::cout << "Error: no shape with name '" << aShapeName << "' found\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;
}
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);
if (hasNormals)
{
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));
}
}
}
}
else if (aCmd == CloudSphere)
{
Standard_Real aCenterX = Draw::Atof (theArgs[2]);
Standard_Real aCenterY = Draw::Atof (theArgs[3]);
Standard_Real aCenterZ = Draw::Atof (theArgs[4]);
Standard_Real aRadius = Draw::Atof (theArgs[5]);
Standard_Integer aNbPoints = Draw::Atoi (theArgs[6]);
TCollection_AsciiString aDistribution = TCollection_AsciiString(theArgs[7]);
aDistribution.LowerCase();
if ( aDistribution != "surface" && aDistribution != "volume" )
{
std::cout << "Error: wrong arguments! See usage:\n";
theDI.PrintHelp (theArgs[0]);
return 1;
}
Standard_Boolean isSurface = aDistribution == "surface";
gp_Pnt aCenter(aCenterX, aCenterY, aCenterZ);
anArrayPoints = new Graphic3d_ArrayOfPoints (aNbPoints, toRandColors, hasNormals);
for (Standard_Integer aPntIt = 0; aPntIt < aNbPoints; ++aPntIt)
{
Standard_Real anAlpha = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
Standard_Real aBeta = (Standard_Real (rand() % 2000) / 1000.0) * M_PI;
Standard_Real aDistance = isSurface ?
aRadius : (Standard_Real (rand() % aNbPoints) / aNbPoints) * aRadius;
gp_Dir aDir (Cos (anAlpha) * Sin (aBeta),
Sin (anAlpha),
Cos (anAlpha) * Cos (aBeta));
gp_Pnt aPoint = aCenter.Translated (aDir.XYZ() * aDistance);
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, aDir);
}
}
}
// 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
//purpose :
@ -5562,4 +5785,21 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
"vvertexmode -set {isolated | all | inherited} - sets the default vertex draw mode and updates the mode for all displayed objects\n"
"vvertexmode -set {isolated | all | inherited} name1 name2 ... - sets the vertex draw mode for the specified object(s)\n",
__FILE__, VVertexMode, group);
theCommands.Add ("vpointcloud",
"vpointcloud name shape [-randColor] [-normals] [-noNormals]"
"\n\t\t: Create an interactive object for arbitary set of points"
"\n\t\t: from triangulated shape."
"\n"
"vpointcloud name x y z r npts {surface|volume}\n"
" ... [-randColor] [-normals] [-noNormals]"
"\n\t\t: Create arbitrary set of points (npts) randomly distributed"
"\n\t\t: on spheric surface or within spheric volume (x y z r)."
"\n\t\t:"
"\n\t\t: Additional options:"
"\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"
"\n",
__FILE__, VPointCloud, group);
}

View File

@ -14,3 +14,5 @@
014 raytrace
015 materials
016 ivtk
017 mesh
018 point_cloud

View File

@ -0,0 +1,30 @@
puts "========"
puts "Point cloud object from triangulated sphere"
puts "========"
# create sphere
sphere ss 10
mkface s ss
incmesh s 0.01
# draw sphere
vinit View1
vclear
vsetdispmode 1
vaxo
vpointcloud p s -nonormals
vaspects p -setcolor GREEN
vfit
vrotate 0.2 0.0 0.0
vdump $::imagedir/${::casename}_green.png
# random colors mode
vpointcloud p s -randcolors
vdump $::imagedir/${::casename}_rand.png
# mode with normals
vpointcloud p s -normals
vsetmaterial p COPPER
vdump $::imagedir/${::casename}_copper.png
vmoveto 200 200