0023743: AIS_Triangulation crashes if Poly_Triangulation has no normals
[occt.git] / src / AIS / AIS_Triangulation.cxx
CommitLineData
b311480e 1// Copyright (c) 1999-2012 OPEN CASCADE SAS
2//
3// The content of this file is subject to the Open CASCADE Technology Public
4// License Version 6.5 (the "License"). You may not use the content of this file
5// except in compliance with the License. Please obtain a copy of the License
6// at http://www.opencascade.org and read it completely before using this file.
7//
8// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
10//
11// The Original Code and all software distributed under the License is
12// distributed on an "AS IS" basis, without warranty of any kind, and the
13// Initial Developer hereby disclaims all such warranties, including without
14// limitation, any warranties of merchantability, fitness for a particular
15// purpose or non-infringement. Please see the License for the specific terms
16// and conditions governing the rights and limitations under the License.
17
7fd59977 18#include <AIS_Drawer.hxx>
19#include <AIS_Triangulation.hxx>
20#include <AIS_InteractiveObject.hxx>
21#include <Standard_DefineHandle.hxx>
22#include <Poly_Array1OfTriangle.hxx>
23#include <Poly_Triangulation.hxx>
24#include <Prs3d_Root.hxx>
25#include <Prs3d_ShadingAspect.hxx>
26#include <TShort_Array1OfShortReal.hxx>
27#include <TColgp_Array1OfPnt.hxx>
28#include <TColStd_HArray1OfInteger.hxx>
29#include <TShort_HArray1OfShortReal.hxx>
30#include <Graphic3d_Group.hxx>
31#include <Graphic3d_AspectFillArea3d.hxx>
32#include <Graphic3d_ArrayOfTriangles.hxx>
7fd59977 33
34
35IMPLEMENT_STANDARD_HANDLE(AIS_Triangulation, AIS_InteractiveObject)
36IMPLEMENT_STANDARD_RTTIEXT(AIS_Triangulation, AIS_InteractiveObject)
37
38AIS_Triangulation::AIS_Triangulation(const Handle(Poly_Triangulation)& Triangulation)
39{
40 myTriangulation = Triangulation;
41 myNbNodes = Triangulation->NbNodes();
42 myNbTriangles = Triangulation->NbTriangles();
43 myFlagColor = 0;
44}
45
46//=======================================================================
47//function : Compute
48//purpose :
49//=======================================================================
50void AIS_Triangulation::Compute(const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
51 const Handle(Prs3d_Presentation)& aPresentation,
52 const Standard_Integer aMode)
53{
54 switch (aMode)
55 {
56 case 0:
57 const TColgp_Array1OfPnt& nodes = myTriangulation->Nodes(); //Nodes
58 const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles(); //Triangle
7fd59977 59
16e65a03 60 Standard_Boolean hasVNormals = myTriangulation->HasNormals();
61 Standard_Boolean hasVColors = (myFlagColor == 1);
7fd59977 62
b8ddfc2f 63 Handle(Graphic3d_ArrayOfTriangles) anArray =
7fd59977 64 new Graphic3d_ArrayOfTriangles ( myNbNodes, //maxVertexs
65 myNbTriangles * 3,//maxEdges
66 hasVNormals, //hasVNormals
67 hasVColors, //hasVColors
68 Standard_False, //hasTexels
69 Standard_True //hasEdgeInfos
70 );
71 Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);
72 Handle(Graphic3d_AspectFillArea3d) aspect = myDrawer->ShadingAspect()->Aspect();
73
74 Standard_Integer i;
75 Standard_Integer j;
76
77 Standard_Real ambient = aspect->FrontMaterial().Ambient();
16e65a03 78 if (hasVNormals)
79 {
80 const TShort_Array1OfShortReal& normals = myTriangulation->Normals();
81 if (hasVColors)
82 {
83 const TColStd_Array1OfInteger& colors = myColor->Array1();
84 for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
85 {
86 j = (i - nodes.Lower()) * 3;
87 anArray->AddVertex(nodes(i), AttenuateColor(colors(i), ambient));
88 anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
89 }
90 }
91 else // !hasVColors
92 {
93 for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
94 {
95 j = (i - nodes.Lower()) * 3;
96 anArray->AddVertex(nodes(i));
97 anArray->SetVertexNormal(i, normals(j+1), normals(j+2), normals(j+3));
98 }
99 }
100 }
101 else // !hasVNormals
102 {
103 if (hasVColors)
104 {
105 const TColStd_Array1OfInteger& colors = myColor->Array1();
106 for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
107 {
108 anArray->AddVertex(nodes(i), AttenuateColor(colors(i), ambient));
109 }
110 }
111 else // !hasVColors
112 {
113 for ( i = nodes.Lower(); i <= nodes.Upper(); i++ )
114 {
115 anArray->AddVertex(nodes(i));
116 }
117 }
7fd59977 118 }
119
120 Standard_Integer indexTriangle[3] = {0,0,0};
121 for ( i = triangles.Lower(); i<= triangles.Upper(); i++ ) {
122 triangles(i).Get(indexTriangle[0], indexTriangle[1], indexTriangle[2]);
b8ddfc2f 123 anArray->AddEdge(indexTriangle[0]);
124 anArray->AddEdge(indexTriangle[1]);
125 anArray->AddEdge(indexTriangle[2]);
7fd59977 126 }
127 TheGroup->SetPrimitivesAspect(aspect);
b8ddfc2f 128 TheGroup->AddPrimitiveArray(anArray);
7fd59977 129 break;
130 }
131}
132
133//=======================================================================
134//function : ComputeSelection
135//purpose :
136//=======================================================================
137void AIS_Triangulation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
138 const Standard_Integer /*aMode*/)
139{
140
141}
142
143//=======================================================================
144//function : SetColor
145//purpose : Set the color for each node.
146// Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
147// Order of color components is essential for further usage by OpenGL
148//=======================================================================
149void AIS_Triangulation::SetColors(const Handle(TColStd_HArray1OfInteger)& aColor)
150{
151 myFlagColor = 1;
152 myColor = aColor;
153}
154
155//=======================================================================
156//function : GetColor
157//purpose : Get the color for each node.
158// Each 32-bit color is Alpha << 24 + Blue << 16 + Green << 8 + Red
159// Order of color components is essential for further usage by OpenGL
160//=======================================================================
161
162Handle(TColStd_HArray1OfInteger) AIS_Triangulation::GetColors() const
163{
164 return myColor;
165}
166
167
168//=======================================================================
169//function : SetTriangulation
170//purpose :
171//=======================================================================
172void AIS_Triangulation::SetTriangulation(const Handle(Poly_Triangulation)& aTriangulation)
173{
174 myTriangulation = aTriangulation;
175}
176
177//=======================================================================
178//function : GetTriangulation
179//purpose :
180//=======================================================================
181Handle(Poly_Triangulation) AIS_Triangulation::GetTriangulation() const{
182 return myTriangulation;
183}
184
185//=======================================================================
186//function : AttenuateColor
187//purpose : Attenuates 32-bit color by a given attenuation factor (0...1):
188// aColor = Alpha << 24 + Blue << 16 + Green << 8 + Red
189// All color components are multiplied by aComponent, the result is then packed again as 32-bit integer.
190// Color attenuation is applied to the vertex colors in order to have correct visual result
191// after glColorMaterial(GL_AMBIENT_AND_DIFFUSE). Without it, colors look unnatural and flat.
192//=======================================================================
193
194Standard_Integer AIS_Triangulation::AttenuateColor( const Standard_Integer aColor,
195 const Standard_Real aComposition)
196{
197 Standard_Integer red,
198 green,
199 blue,
200 alpha;
201
202 alpha = aColor&0xff000000;
203 alpha >>= 24;
204
205 blue = aColor&0x00ff0000;
206 blue >>= 16;
207
208 green = aColor&0x0000ff00;
209 green >>= 8;
210
211 red = aColor&0x000000ff;
212 red >>= 0;
213
214 red = (Standard_Integer)(aComposition * red);
215 green = (Standard_Integer)(aComposition * green);
216 blue = (Standard_Integer)(aComposition * blue);
217
218 Standard_Integer color;
219 color = red;
220 color += green << 8;
221 color += blue << 16;
222 color += alpha << 24;
223 return color;
224}
225