How to Display AIS_SHAPE wireframe ?

Hello,

I have an AIS_SHAPE the I can display in Shaded Mode or Wireframe Mode (method SetDisplayMode()), but how can I display a solid object in shaded mode with his wireframe ?

The problem is that some objects are not rendered in a clear mode without their wireframe.

Thanks,

Fabian Hachenberg's picture

Do you want to render the edges as wires on top of the shaded surface of the solid?
In that case you could simply add the wires as additional AIS_Shape objects to the context

Francois Lauzon's picture

Hello,
the AIS_Shape doesn't support the mix of wireframe and shading. What we did here was to add that support to the AIS_Shape itself when the shape is displayed with no transparency. Like you, we needed that to help visualize the shape.

Here is a sample of the Compute method of AIS_Shape for release 6.4.0. I'll let you check what is different with you current file...

Good Luck,
Francois.

//=======================================================================
//function : Compute
//purpose :
//=======================================================================
void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
const Handle(Prs3d_Presentation)& aPrs,
const Standard_Integer aMode)
{
aPrs->Clear();
if(myshape.IsNull()) return;

// wire,edge,vertex -> pas de HLR + priorite display superieure
Standard_Integer TheType = (Standard_Integer) myshape.ShapeType();
if(TheType>4 && TheType<8) {
aPrs->SetVisual(Graphic3d_TOS_ALL);
aPrs->SetDisplayPriority(TheType+2);
}
// Shape vide -> Assemblage vide.
if (myshape.ShapeType() == TopAbs_COMPOUND) {
#ifdef BUC60547
TopoDS_Iterator anExplor (myshape);
#else
TopExp_Explorer anExplor (myshape, TopAbs_VERTEX);
#endif
if (!anExplor.More()) {
return;
}
}

if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //pas de prise en compte lors du FITALL
switch (aMode) {
case 0:{
try {
// set temp color and with
Handle_Prs3d_LineAspect wireAspect=myDrawer->FreeBoundaryAspect();
Quantity_Color color;
Color(color);
wireAspect->SetColor(color);
wireAspect->SetWidth(1.);
myDrawer->SetFreeBoundaryAspect(wireAspect);
wireAspect=myDrawer->UnFreeBoundaryAspect();
wireAspect->SetColor(Quantity_NOC_YELLOW);
wireAspect->SetWidth(1.);
myDrawer->SetUnFreeBoundaryAspect(wireAspect);
StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
}
catch (Standard_Failure) {
#ifdef DEB
std::cout << "AIS_Shape::Compute() failed"<< std::endl;
#endif
std::cout << "a Shape should be incorrect : No Compute can be maked on it "<< std::endl;
// on calcule une presentation de la boite englobante
// Compute(aPresentationManager,aPrs,2);
}
break;
}
case 1:
{
Standard_Real prevangle ;
Standard_Real newangle ;
Standard_Real prevcoeff ;
Standard_Real newcoeff ;
Standard_Boolean ownDevAngle=OwnDeviationAngle(newangle,prevangle);
Standard_Boolean ownDevCoeff=OwnDeviationCoefficient(newcoeff,prevcoeff);

if (ownDevAngle || ownDevCoeff)
if (Abs (newangle - prevangle) > Precision::Angular() ||
Abs (newcoeff - prevcoeff) > Precision::Confusion() ) {
#ifdef DEB
std::cout << "AIS_Shape : compute"<4)
StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
else {
myDrawer->SetShadingAspectGlobal(Standard_False);
if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
else {
{
try {
OCC_CATCH_SIGNALS
StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer);
}
catch (Standard_Failure) {
#ifdef DEB
std::cout << "AIS_Shape::Compute() in ShadingMode failed"<< std::endl;
#endif
StdPrs_WFShape::Add(aPrs,myshape,myDrawer);
}
}
}
}
#ifdef BUC60918
Standard_Real value = Transparency() ;
if( value > 0. ) {
SetTransparency( value );
}
#endif

// set temp color and with
if( Abs(value) FreeBoundaryAspect();
wireAspect->SetColor(Quantity_NOC_BLACK);
wireAspect->SetWidth(0.5);
myDrawer->SetFreeBoundaryAspect(wireAspect);
wireAspect=myDrawer->UnFreeBoundaryAspect();
wireAspect->SetColor(Quantity_NOC_BLACK);
wireAspect->SetWidth(0.5);
myDrawer->SetUnFreeBoundaryAspect(wireAspect);

DrawEdges(aPrs,myshape,myDrawer);
}
break;
}
case 2:
{
// boite englobante
if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer);
else DisplayBox(aPrs,BoundingBox(),myDrawer);
}

} // end switch
aPrs->ReCompute(); // for hidden line recomputation if necessary...

}

Francois Lauzon's picture

I forgot, you will need DrawEdge and DrawPolygon if you're planning on using that.

static Standard_Boolean AddPolygon(const TopoDS_Edge& E,
Handle(Graphic3d_Group)& TheGroup,
const Standard_Real deflection,
const Handle (Prs3d_Drawer)& aDrawer)
{
TopLoc_Location l;
gp_Pnt P;
Standard_Boolean result = Standard_False;
Standard_Boolean OK;
Standard_Real fi, la;

Handle(Poly_Polygon3D) Polyg;
Handle(Geom_Curve) CC3d = BRep_Tool::Curve(E, fi, la);

Polyg = BRep_Tool::Polygon3D(E, l);
if (!Polyg.IsNull()) {
OK = Polyg->Deflection() <= deflection;
OK = OK || (CC3d.IsNull());

if (Polyg->Deflection() <= deflection) {
result = Standard_True;
const TColgp_Array1OfPnt& Points = Polyg->Nodes();
Graphic3d_Array1OfVertex V(1, Points.Length());
Standard_Integer po, ii = 1;
if (l.IsIdentity()) {
for (po = Points.Lower(); po <= Points.Upper(); po++) {
P = Points.Value(po);
V(ii).SetCoord(P.X(), P.Y(), P.Z());
ii++;
}
}
else {
for (po = Points.Lower(); po <= Points.Upper(); po++) {
P = Points.Value(po).Transformed(l);
V(ii).SetCoord(P.X(), P.Y(), P.Z());
ii++;
}
}
TheGroup->Polyline(V);
return result;
}
}

Handle(Poly_Triangulation) Tr;
Handle(Poly_PolygonOnTriangulation) HIndices;
BRep_Tool::PolygonOnTriangulation(E, HIndices, Tr, l);
if (!HIndices.IsNull()) {

OK = HIndices->Deflection() <= deflection;
OK = OK || (CC3d.IsNull());

if (OK) {
result = Standard_True;
const TColStd_Array1OfInteger& Indices = HIndices->Nodes();
const TColgp_Array1OfPnt& Nodes = Tr->Nodes();
Graphic3d_Array1OfVertex V(1, Indices.Length());

Standard_Integer po, ii = 1;
if (l.IsIdentity()) {
for (po = Indices.Lower(); po <= Indices.Upper(); po++) {
P = Nodes(Indices(po));
V(ii).SetCoord(P.X(), P.Y(), P.Z());
ii++;
}
}
else {
for (po = Indices.Lower(); po <= Indices.Upper(); po++) {
P = Nodes(Indices(po)).Transformed(l);
V(ii).SetCoord(P.X(), P.Y(), P.Z());
ii++;
}
}
TheGroup->Polyline(V);
return result;
}
}
return result;
}

void
DrawEdges(const Handle(Prs3d_Presentation)& aPrs,
const TopoDS_Shape& aShape,
const Handle (Prs3d_Drawer)& aDrawer)
{
if (aShape.IsNull()) return;

Prs3d_ShapeTool Tool(aShape);

TopTools_ListOfShape LFree, LUnFree, LWire;
for(Tool.InitCurve();Tool.MoreCurve();Tool.NextCurve()){
Standard_Integer neigh = Tool.Neighbours();
const TopoDS_Edge& E = Tool.GetCurve();
if (neigh >= 2) {
LUnFree.Append(E);
}
else if (neigh == 1) {
LFree.Append(E);
}
else if (neigh == 0) {
LWire.Append(E);
}
}

TopTools_ListIteratorOfListOfShape It;

Handle(Graphic3d_Group) TheGroup = Prs3d_Root::NewGroup(aPrs);
Standard_Real aDeflection;
Aspect_TypeOfDeflection TOD = aDrawer->TypeOfDeflection();

if (TOD == Aspect_TOD_RELATIVE) {
// On calcule la fleche en fonction des min max globaux de la piece:

Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
aDeflection = aDrawer->MaximalChordialDeviation();
Bnd_Box Total;
BRepBndLib::Add(aShape, Total);

Total.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
aDeflection = MAX3( aXmax-aXmin , aYmax-aYmin , aZmax-aZmin)
* aDrawer->DeviationCoefficient();
}
else {
aDeflection = aDrawer->MaximalChordialDeviation();
}

if (aDrawer->WireDraw()) {
// Wire (without any neighbour)
TheGroup->SetPrimitivesAspect(aDrawer->WireAspect()->Aspect());
TheGroup->BeginPrimitives();
for (It.Initialize(LWire); It.More(); It.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(It.Value());
try {
if (!AddPolygon(E, TheGroup, aDeflection, aDrawer)) {
if (BRep_Tool::IsGeometric(E)) {
BRepAdaptor_Curve C(E);
TColgp_SequenceOfPnt Points;
StdPrs_DeflectionCurve::Add(aPrs, C, aDeflection, aDrawer,Points);
}
}
}
catch(Standard_Failure) {
}
}
TheGroup->EndPrimitives();
}

if (aDrawer->FreeBoundaryDraw()) {

// Free boundaries;
TheGroup->SetPrimitivesAspect(aDrawer->FreeBoundaryAspect()->Aspect());
TheGroup->BeginPrimitives();
for (It.Initialize(LFree); It.More(); It.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(It.Value());
if (!BRep_Tool::Degenerated(E)) {
try {
if (!AddPolygon(E, TheGroup, aDeflection, aDrawer)) {
if (BRep_Tool::IsGeometric(E)) {
BRepAdaptor_Curve C(E);
TColgp_SequenceOfPnt Points;
StdPrs_DeflectionCurve::Add(aPrs, C, aDeflection, aDrawer,Points);
}
}
}
catch(Standard_Failure) {
}
}
}
TheGroup->EndPrimitives();
}

if (aDrawer->UnFreeBoundaryDraw()) {

// Unfree boundaries;

TheGroup->SetPrimitivesAspect(aDrawer->UnFreeBoundaryAspect()->Aspect());
TheGroup->BeginPrimitives();
for (It.Initialize(LUnFree); It.More(); It.Next()) {
const TopoDS_Edge& E = TopoDS::Edge(It.Value());
try {
if (!AddPolygon(E, TheGroup, aDeflection, aDrawer)) {
if (BRep_Tool::IsGeometric(E)) {
BRepAdaptor_Curve C(E);
TColgp_SequenceOfPnt Points;
StdPrs_DeflectionCurve::Add(aPrs, C, aDeflection, aDrawer,Points);
}
}
}
catch(Standard_Failure) {
}
}
TheGroup->EndPrimitives();
}

}

SunHongLei's picture

hello,François Lauzon,I want to display a model in wireframe way which appears like opencascade and I want to get the discrete data so i can display with opengl. So I want to ask do you know how opencascade dicrete a model?

Venugopal Gudimetla's picture

Thanks François for sharing the code. I was looking for this too.

Venu

Marco Balen's picture

Thanks for your prompt answer,
I will try the 2 solutions in the next days,

Thanks to everybody

Fotis Sioutis's picture

Hello,

I believe that the initial design of OCC visualization had in mind such a case where the edges should be displayed at the same time with the shading.One could track down to the first releases that the Prs3d_ShadingAspect class of visualization provides a call to set the edges on.Without investigating deeper i think that the usage of Prs3d_ShadingAspect::SetEdgeOn() of this class uses the underlying OpenGL::glEdgeFlag for the drawn primitives (a better way to provide such feature than re-drawing the edges in my opinion).Unfortunatelly while this feature works for simple shapes it seems that there is a bug which registers non-edge primitives as edge ones and with complex shapes it does not work as intended.Maybe if time allows i will dig a bit deeper and try to find the root of the problem.If anyone knows something more on this issue i would be glad to hear about.

Fotis