Colored curvature visualization for surface

Hi,

I'd like to display the curvature of a surface directly over the surface using colours, this functionnality is very usefull when checking continuity (or smoothness) of a surface during the modeling process. To achieve this goal I think I can proceed like this (I removed some code lines not very usefull):

//Starting with a Geom_Bspline surface...
//Get the TopoDS_Shape corresponding to the surface
TopoDS_Shell myShape = BRepBuilderAPI_MakeShell(mySurface);

//Compute the triangulation of the surface and add it to the shape definition
BRepMesh::Mesh(myShape,myDeflection);

//Initialize graphic parameters
Handle(Graphic3d_AspectFillArea3d) myAspect = (new Prs3d_ShadingAspect())->Aspect();
myAspect->SetInteriorStyle(Aspect_IS_SOLID);

//Explore the shape and get all the triangles of the corresponding mesh
TopExp_Explorer ExpFace;
Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, myLocation);
Poly_Connect pc(myT);
const TColgp_Array1OfPnt& Nodes = myT->Nodes();
const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
const Poly_Array1OfTriangle& triangles = myT->Triangles();

//For each triangle get the three nodes
Graphic3d_Array1OfVertexNC Points(1,3);
Aspect_Array1OfEdge aretes(1,3);

mygroup->BeginPrimitives();
{
gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());

Points(1).SetCoord(p.X(), p.Y(), p.Z());
Points(2).SetCoord(q.X(), q.Y(), q.Z());
Points(3).SetCoord(r.X(), r.Y(), r.Z());

if(myT->HasUVNodes())
{
TRACE("UV values for Node ni : U=%f V=%f \n",UVNodes(ni).X(),UVNodes(ni).Y());

// Compute local properties for Node ni
aSLProps.SetParameters(UVNodes(ni).X(),UVNodes(ni).Y());
if(aSLProps.IsCurvatureDefined())
{
aSLProps.MinCurvature();
aSLProps.MaxCurvature();
aSLProps.MeanCurvature();
aSLProps.GaussianCurvature();
TRACE("Curvature values...")
}

// Add a color parameter to the nodes to visualize local curvature based on the previous results
Points(1).SetColor(ColorMap...);
Points(2).SetColor(ColorMap...);
Points(3).SetColor(ColorMap...);
}

Points(1).SetNormal(myNormal(n1).X(), myNormal(n1).Y(), myNormal(n1).Z());
Points(2).SetNormal(myNormal(n2).X(), myNormal(n2).Y(), myNormal(n2).Z());
Points(3).SetNormal(myNormal(n3).X(), myNormal(n3).Y(), myNormal(n3).Z());

aretes(1).SetValues(1, 2, Aspect_TOE_INVISIBLE);
aretes(2).SetValues(2, 3, Aspect_TOE_INVISIBLE);
aretes(3).SetValues(3, 1, Aspect_TOE_INVISIBLE);
}
mygroup->EndPrimitives();
mygroup->TriangleSet(Points, aretes, Standard_True);

The code works fine, for each node I get curvature values that seem to be correct. But the triangles are not rendered based on the their vertex color (shading composed of the vertex colors).

I used the following parameters for the V3d_Viewer and tested all the other modes of default shading model without any positive changes:
myViewer = new V3d_Viewer(theGraphicDevice,(short *) "Visu3D");
myViewer->SetDefaultLights();
myViewer->SetLightOn();
myViewer->SetDefaultBackgroundColor(Quantity_NOC_GRAY50);
//myViewer->SetDefaultShadingModel(V3d_COLOR);
//myViewer->SetDefaultShadingModel(V3d_MULTICOLOR);
//myViewer->SetDefaultShadingModel(V3d_FLAT);
myViewer->SetDefaultShadingModel(V3d_GOURAUD);
//myViewer->SetDefaultShadingModel(V3d_HIDDEN);
myViewer->SetDefaultVisualization(V3d_ZBUFFER);
myViewer->SetDefaultSurfaceDetail(V3d_TEX_ALL);

Maybe I should use a diffrent group for each triangle!?
What's the purpose of VertexNC in TriangleSet if not to perform such a function?
What about Graphic3d_Structure, is this object usefull in this case?

In fact I'm not sure one can display a triangle based on different colored vertex in OCC, using some kind of OPEN_GL GL_SMOOTH parameters fo shading.

By the way can anyone tell me what is the purpose of the (V3d_MULTICOLOR: interpolated colors) parameter available for the V3d_Viewer object.

As you can see the function is quite simple and the OCC implementation quite hard, but I'm sure some of you already faced this and found something.

Thanks by advance.

Francois Lauzon's picture

Hello Thierry,
I know it's not working with all settings in the Fill Area, here is what I do and it's working:

// get the current group
Handle_Graphic3d_Group aGroup=Prs3d_Root::CurrentGroup(aPrs3d);

// fill the array
Graphic3d_Array1OfVertexC anArray(1,...);

// build edge list
Aspect_Array1OfEdge anEdges(1,...);

// create a new default Fill Area and just set the interior style
Handle_Graphic3d_AspectFillArea3d CTX=new Graphic3d_AspectFillArea3d();
CTX->SetInteriorStyle(Aspect_IS_SOLID);
aGroup->SetPrimitivesAspect(CTX);
aGroup->BeginPrimitives();
aGroup->TriangleSet(anArray,anEdges);
aGroup->EndPrimitives();

PS. You also need the latest version of OCC, because there used to have a bug in ealier version that was corrected in version 5.1 I think (maybe 5.0 but I'm not sure)

Good Luck,
Francois.

tlacombe's picture

Hi François,

I'm using OCC 5.1 and it works.

Thanks a lot for the tip and for answering so fast.

Thierry

白晓亮(Bai Xiaolian's picture

Hi,
Handle( Graphic3d_Group ) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);

how to get aPresentation object?

thanks.

白晓亮(Bai Xiaolian's picture

Hi,
Sorry for my rashness.
Sames user_cylinder.cpp have all inf I need.

Regards.

Bai Xiaoliang