AECSoft

专注于AEC行业软件开发15年

导航

[原创]HOW TO: OCC中渲染状态下显示Shape边线(Edge)的最佳实践

作者:spas

n年前曾经用过Open Cascade,嫌太慢放弃了,现在升到6.3版本,速度有了很大提升。刚好工作中有需要,就好好研究了一下。本篇是介绍如何在渲染状态下显示Shape边线(Edge)的最佳实践。找了很多地方都没有找到,只好自己摸索。现贴出来与大家共享。

实践一

假设shape是一个已经生成的TopoDS_Shape对象。如下代码:

//显示ShapeHandle (AIS_MyShape)
ais =newAIS_MyShape(shape);
myAISContext->SetColor(ais,qcolor,Standard_False);
myAISContext->SetMaterial(ais,material,Standard_False);
myAISContext->SetTransparency(ais, transparency/10.0,Standard_False);
myAISContext->SetDisplayMode(ais,1,Standard_False);
myAISContext->Display(ais, updateview);

//生成边线组
BRep_Builder builder;
TopoDS_Compound comp;
builder.MakeCompound(comp);
for(TopExp_Explorer ex(shape,TopAbs_EDGE) ; ex.More(); ex.Next())
{
   TopoDS_Edge F =TopoDS::Edge(ex.Current());
   builder.Add(comp, F);
}

//显示边线组
Handle (AIS_Shape) compShape =newAIS_Shape(comp);
myAISContext->SetColor(compShape, myEdgeColor,Standard_False);
myAISContext->Display(compShape, updateview);
这种方法的缺点:由于对一个物体生成了两个AIS_Shape,故在进行数据管理时会引起更复杂的编码。

最佳实践:

思路:从继承自己的Shape,定制其显示行为。如下代码:


// File: AIS_MyShape.hxx
// Created: 2009.4.1
// Author: Z. C.

#ifndef _AIS_MyShape_HeaderFile
#define _AIS_MyShape_HeaderFile
#include <Standard_DefineHandle.hxx>

class TopoDS_Shape;

DEFINE_STANDARD_HANDLE(AIS_MyShape, AIS_Shape)

class AIS_MyShape :publicAIS_Shape
{
public:
DEFINE_STANDARD_RTTI(AIS_MyShape)
AIS_MyShape(intkey,const TopoDS_Shape& aShape);
~AIS_MyShape();
Standard_Boolean IsKind(constHandle(Standard_Type)& AType)const;

protected:
virtual void Compute(constHandle(PrsMgr_PresentationManager3d)& aPresentationManager,constHandle(Prs3d_Presentation)& aPresentation,constStandard_Integer aMode = 0) ;
int myKey;
};

inline Standard_Boolean AIS_MyShape::IsKind(constHandle(Standard_Type)& AType)const
{return(STANDARD_TYPE(AIS_MyShape) == AType || AIS_Shape::IsKind(AType)); }


#endif

// File: AIS_MyShape.cxx
// Created: 2009.4.1
// Author: Z. C.

#include"stdafx.h"
#include <Prs3d_LineAspect.hxx>
#include <StdPrs_Curve.hxx>
#include <StdPrs_ShadedShape.hxx>
#include <StdPrs_WFDeflectionShape.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
#include <Graphic3d_Group.hxx>
#include <Graphic3d_Structure.hxx>
#include <Graphic3d_AspectLine3d.hxx>
#include <Graphic3d_Array1OfVertex.hxx>
#include"AIS_MyShape.hxx"

IMPLEMENT_STANDARD_HANDLE(AIS_MyShape,AIS_Shape)
IMPLEMENT_STANDARD_RTTI(AIS_MyShape,AIS_Shape)

//
// Foreach ancestors, we add a IMPLEMENT_STANDARD_SUPERTYPE and
// a IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY macro.
// We must respect the order: from the direct ancestor class
// to the base class.
//
IMPLEMENT_STANDARD_TYPE(AIS_MyShape)
        IMPLEMENT_STANDARD_SUPERTYPE(AIS_Shape)
        IMPLEMENT_STANDARD_SUPERTYPE(AIS_InteractiveObject)
        IMPLEMENT_STANDARD_SUPERTYPE(SelectMgr_SelectableObject)
        IMPLEMENT_STANDARD_SUPERTYPE(PrsMgr_PresentableObject)
        IMPLEMENT_STANDARD_SUPERTYPE(MMgt_TShared)
        IMPLEMENT_STANDARD_SUPERTYPE(Standard_Transient)
        IMPLEMENT_STANDARD_SUPERTYPE_ARRAY()
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(AIS_Shape)
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(AIS_InteractiveObject)
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(SelectMgr_SelectableObject)
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(PrsMgr_PresentableObject)
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(MMgt_TShared)
                IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(Standard_Transient)
        IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END()
IMPLEMENT_STANDARD_TYPE_END(AIS_MyShape)


AIS_MyShape::AIS_MyShape(intkey,constTopoDS_Shape& aShape) : AIS_Shape(aShape)
{ myKey = key; }

AIS_MyShape::~AIS_MyShape() { }

//=======================================================================
//function : Compute
//purpose :
//=======================================================================
void AIS_MyShape::Compute(constHandle(PrsMgr_PresentationManager3d)& aPresentationManager,constHandle(Prs3d_Presentation)& aPrs,constStandard_Integer aMode)
{
AIS_Shape::Compute(aPresentationManager, aPrs, aMode);

//Handle(Graphic3d_Group) G = Prs3d_Root::CurrentGroup(aPrs); 不能用CurrentGroup
Handle_Graphic3d_Structure theStructure = Handle_Graphic3d_Structure::DownCast(aPrs);
Handle_Graphic3d_Group G=newGraphic3d_Group(theStructure);

//Handle(AIS_Drawer) aDrawer =newAIS_Drawer();
//Quantity_Color Q;
//Aspect_TypeOfLine A;
//Standard_Real W;
//aDrawer->LineAspect()->Aspect()->Values(Q,A,W);

G->SetGroupPrimitivesAspect(newGraphic3d_AspectLine3d(Quantity_NOC_BLACK, Aspect_TOL_DASH, 0.1));

Standard_Real c_start;
Standard_Real c_end;

Graphic3d_Array1OfVertex VVV (1,2);

G->BeginPrimitives();
for(TopExp_Explorer ex(myshape,TopAbs_EDGE) ; ex.More(); ex.Next())
{
TopoDS_Edge edge =TopoDS::Edge(ex.Current());
Handle(Geom_Curve) c = BRep_Tool::Curve(edge, c_start, c_end);//一个无限的曲线
Handle(Geom_TrimmedCurve) myTrimmed =newGeom_TrimmedCurve(c, c_start, c_end);//转换成有限曲线

//这段代码只能处理直线,故注释
//VVV.SetValue(1, Graphic3d_Vertex(myTrimmed->StartPoint().X(), myTrimmed->StartPoint().Y(), myTrimmed->StartPoint().Z()));
//VVV.SetValue(2, Graphic3d_Vertex(myTrimmed->EndPoint().X(), myTrimmed->EndPoint().Y(), myTrimmed->EndPoint().Z()));
//G->Polyline(VVV);

//上面三行注释掉的代码替换为如下代码
GeomAdaptor_Curve anAdaptorCurve(myTrimmed);

Standard_Integer NbPoints = myDrawer->Discretisation();
Standard_Real V1, V2;
FindLimits(anAdaptorCurve, myDrawer->MaximalParameterValue(), V1, V2);

TColgp_SequenceOfPnt Pnts;
DrawCurve(anAdaptorCurve, G, NbPoints, V1 , V2, Pnts, Standard_True);
}
G->EndPrimitives();

}


以上代码用到的函数:
{Code}static Standard_Integer myN = -1;
static Standard_Boolean first = Standard_True;

//==================================================================
// function: FindLimits
// purpose:
//==================================================================
static void FindLimits(const Adaptor3d_Curve& aCurve,
         const Standard_Real aLimit,
         Standard_Real&       First,
         Standard_Real&       Last)
{
First = aCurve.FirstParameter();
Last = aCurve.LastParameter();
Standard_Boolean firstInf = Precision::IsNegativeInfinite(First);
Standard_Boolean lastInf = Precision::IsPositiveInfinite(Last);

if (firstInf || lastInf) {
    gp_Pnt P1,P2;
    Standard_Real delta = 1;
    if (firstInf && lastInf) {
      do {
delta *= 2;
First = - delta;
Last =   delta;
aCurve.D0(First,P1);
aCurve.D0(Last,P2);
      } while (P1.Distance(P2) < aLimit);
    }
    else if (firstInf) {
      aCurve.D0(Last,P2);
      do {
delta *= 2;
First = Last - delta;
aCurve.D0(First,P1);
      } while (P1.Distance(P2) < aLimit);
    }
    else if (lastInf) {
      aCurve.D0(First,P1);
      do {
delta *= 2;
Last = First + delta;
aCurve.D0(Last,P2);
      } while (P1.Distance(P2) < aLimit);
    }
}
}

//==================================================================
// function: DrawCurve
// purpose:
//==================================================================
static void DrawCurve (const Adaptor3d_Curve&               aCurve,
                       const Handle(Graphic3d_Group) aGroup,
         const Standard_Integer        NbP,
                       const Standard_Real           U1,
                       const Standard_Real           U2,
         TColgp_SequenceOfPnt&         Points,
         const Standard_Boolean drawCurve)
{
Standard_Integer nbintervals = 1;

if (aCurve.GetType() == GeomAbs_BSplineCurve) {
    nbintervals = aCurve.NbKnots() - 1;
    nbintervals = Max(1, nbintervals/3);
}

Standard_Boolean isPrimArrayEnabled = Graphic3d_ArrayOfPrimitives::IsEnable() && !drawCurve;
switch (aCurve.GetType()) {
case GeomAbs_Line:
    {
#ifdef OCC64
      Graphic3d_Array1OfVertex VertexArray(1, 3);
      gp_Pnt p = aCurve.Value(U1);
      Points.Append(p);
      VertexArray(1).SetCoord(p.X(), p.Y(), p.Z());
      p = aCurve.Value(0.5 * (U1 + U2));
      Points.Append(p);
      VertexArray(2).SetCoord(p.X(), p.Y(), p.Z());
      p = aCurve.Value(U2);
      Points.Append(p);
      VertexArray(3).SetCoord(p.X(), p.Y(), p.Z());
      if(!isPrimArrayEnabled)
aGroup->Polyline(VertexArray);
#else
     static Graphic3d_Array1OfVertex VertexLine(1,2);
     gp_Pnt p = aCurve.Value(U1);
     Points.Append(p);
     VertexLine(1).SetCoord(p.X(), p.Y(), p.Z());
     p = aCurve.Value(U2);
     Points.Append(p);
     VertexLine(2).SetCoord(p.X(), p.Y(), p.Z());
     if(!isPrimArrayEnabled)
       aGroup->Polyline(VertexLine);
#endif
   }
    break;
default:
    {
      Standard_Real U;
      Standard_Integer N = Max(2, NbP*nbintervals);
      Standard_Real DU = (U2-U1) / (N-1);
      gp_Pnt p;

      if (first) {
myN = N;
first = Standard_False;
      }
      if (myN == N) {

static Graphic3d_Array1OfVertex VertexArray(1, N);

for (Standard_Integer i = 1; i <= N;i++) {
   U = U1 + (i-1)*DU;
   p = aCurve.Value(U);
   Points.Append(p);
   VertexArray(i).SetCoord(p.X(), p.Y(), p.Z());
}
if(!isPrimArrayEnabled)
   aGroup->Polyline(VertexArray);
      }
      else {
Graphic3d_Array1OfVertex VertexArray2(1, N);

for (Standard_Integer i = 1; i <= N;i++) {
   U = U1 + (i-1)*DU;
   p = aCurve.Value(U);
   Points.Append(p);
   VertexArray2(i).SetCoord(p.X(), p.Y(), p.Z());
}
if(!isPrimArrayEnabled)
   aGroup->Polyline(VertexArray2);
      }
    }
}
}

Enjoy it!

阅读全文
类别:信息技术 查看评论

posted on 2009-04-06 18:17  zuoc  阅读(2259)  评论(0编辑  收藏  举报