0028105: HLR rendering crash in MFC sample
[occt.git] / samples / mfc / standard / Common / User_Cylinder.cxx
CommitLineData
7fd59977 1#include <stdafx.h>
2
3#include <User_Cylinder.hxx>
4
5// Implementation of Handle and type mgt
6//
92efcf78 7
7fd59977 8IMPLEMENT_STANDARD_RTTIEXT(User_Cylinder,AIS_InteractiveObject)
9
10#include "ColoredMeshDlg.h"
11
1a4b0f54 12#include <Graphic3d_ArrayOfTriangles.hxx>
7fd59977 13#include <Graphic3d_StructureManager.hxx>
14#include <PrsMgr_PresentationManager3d.hxx>
5ad8c033 15#include <StdPrs_ToolTriangulatedShape.hxx>
7fd59977 16#include <Poly_Connect.hxx>
17#include <TColgp_Array1OfPnt.hxx>
18#include <Poly_Triangulation.hxx>
19#include <TColgp_Array1OfDir.hxx>
20#include <GProp_PGProps.hxx>
7fd59977 21#include <Quantity_Color.hxx>
9a148b08 22#include <BRepMesh_IncrementalMesh.hxx>
16aec6a4 23#include <Prs3d.hxx>
7fd59977 24
25#include <AIS_GraphicTool.hxx>
26
27// Constructors implementation
28//
29
30User_Cylinder::User_Cylinder(const Standard_Real R, const Standard_Real H) :
31AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
32{
5c1f974e 33 BRepPrimAPI_MakeCylinder S(R,H);
34 myShape = S.Shape();
35 SetHilightMode(0);
5c1f974e 36 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
4208cf18 37 myColor = Quantity_NOC_GRAY;
7fd59977 38}
39
40User_Cylinder::User_Cylinder(const gp_Ax2 CylAx2, const Standard_Real R, const Standard_Real H) :
41AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
42
43{
5c1f974e 44 BRepPrimAPI_MakeCylinder S(CylAx2,R,H);
45 BRepBuilderAPI_NurbsConvert aNurbsConvert(S.Shape());
46 myShape = aNurbsConvert.Shape();
47 SetHilightMode(0);
5c1f974e 48 myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
4208cf18 49 myColor = Quantity_NOC_KHAKI4;
7fd59977 50}
51
92efcf78 52void User_Cylinder::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
53 const Handle(Prs3d_Presentation)& aPresentation,
5c1f974e 54 const Standard_Integer aMode )
7fd59977 55{
5c1f974e 56 switch (aMode) {
4208cf18 57case AIS_WireFrame:
58 {
59 StdPrs_WFShape::Add(aPresentation,myShape, myDrawer );
60 break;
61 }
62case AIS_Shaded:
5c1f974e 63 {
5c1f974e 64 Standard_Real aTransparency = Transparency();
65 Graphic3d_NameOfMaterial aMaterial = Material();
4208cf18 66 myDrawer->ShadingAspect()->SetMaterial(aMaterial);
67 myDrawer->ShadingAspect()->SetColor(myColor);
68 myDrawer->ShadingAspect()->SetTransparency (aTransparency);
69 StdPrs_ShadedShape::Add(aPresentation,myShape, myDrawer);
5c1f974e 70 break;
5c1f974e 71 }
72case 6: //color
73 {
74 BRepTools::Clean(myShape);
75 BRepTools::Update(myShape);
76
77 Handle(Graphic3d_StructureManager) aStrucMana = GetContext()->MainPrsMgr()->StructureManager();
78
79 Handle(Graphic3d_Group) mygroup = Prs3d_Root::CurrentGroup(aPresentation);
80 myAspect = (new Prs3d_ShadingAspect())->Aspect();
81 Graphic3d_MaterialAspect material = myAspect->FrontMaterial();
82 material.SetReflectionModeOff(Graphic3d_TOR_AMBIENT);
83 material.SetReflectionModeOff(Graphic3d_TOR_DIFFUSE);
84 material.SetReflectionModeOff(Graphic3d_TOR_SPECULAR);
85 material.SetReflectionModeOff(Graphic3d_TOR_EMISSION);
86 myAspect->SetFrontMaterial(material);
87
88 mygroup->SetPrimitivesAspect(myAspect);
89 myAspect->SetEdgeOn();
90
16aec6a4 91 myDeflection = Prs3d::GetDeflection(myShape,myDrawer);
9a148b08 92 BRepMesh_IncrementalMesh(myShape,myDeflection);
5c1f974e 93
94 myX1OnOff = Standard_False;
95 myXBlueOnOff = Standard_False;
96 myXGreenOnOff =Standard_False;
97 myXRedOnOff = Standard_False;
98 myY1OnOff = Standard_False;
99 myYBlueOnOff = Standard_False;
100 myYGreenOnOff = Standard_False;
101 myYRedOnOff = Standard_False;
102 myZ1OnOff = Standard_False;
103 myZBlueOnOff =Standard_False;
104 myZGreenOnOff = Standard_False;
105 myZRedOnOff = Standard_False;
106
107 CColoredMeshDlg Dlg(NULL);
108 Dlg.DoModal();
109
110 myX1OnOff = Dlg.X1OnOff;
111
dde68833 112 myXBlueOnOff = Dlg.m_CheckXBlueOnOff != 0;
113 myXGreenOnOff = Dlg.m_CheckXGreenOnOff != 0;
114 myXRedOnOff = Dlg.m_CheckXRedOnOff != 0;
5c1f974e 115
116 myY1OnOff = Dlg.Y1OnOff;
117
dde68833 118 myYBlueOnOff = Dlg.m_CheckYBlueOnOff != 0;
119 myYGreenOnOff = Dlg.m_CheckYGreenOnOff != 0;
120 myYRedOnOff = Dlg.m_CheckYRedOnOff != 0;
5c1f974e 121
122 myZ1OnOff = Dlg.Z1OnOff;
123
dde68833 124 myZBlueOnOff = Dlg.m_CheckZBlueOnOff != 0;
125 myZGreenOnOff = Dlg.m_CheckZGreenOnOff != 0;
126 myZRedOnOff = Dlg.m_CheckZRedOnOff != 0;
5c1f974e 127
128 // Adds a triangulation of the shape myShape to its topological data structure.
129 // This triangulation is computed with the deflection myDeflection.
7fd59977 130
131#ifdef DEBUG
5c1f974e 132 cout <<"Deflection = " << myDeflection << "\n" << endl;
7fd59977 133#endif
134
5c1f974e 135 Standard_Integer NumFace;
136 TopExp_Explorer ExpFace;
7fd59977 137
5c1f974e 138 //khr -->
7fd59977 139
5c1f974e 140 gp_Pnt H (0,0,0);
141 gp_Pnt B (0,0,1000000000);
142 for( NumFace=0,ExpFace.Init(myShape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
143 {
144 TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
145 TopLoc_Location myLocation = myFace.Location();
7fd59977 146
147#ifdef DEBUG
5c1f974e 148 cout << "J\'explore actuellement la face " << NumFace << "\n" << endl;
7fd59977 149#endif
5c1f974e 150 Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, myLocation);
151 // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
7fd59977 152
5c1f974e 153 if (myT.IsNull())
154 {
7fd59977 155#ifdef DEBUG
5c1f974e 156 // cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
7fd59977 157#endif
5c1f974e 158 return;
159 }
160
161 const TColgp_Array1OfPnt& Nodes= myT->Nodes();
162
163 const Poly_Array1OfTriangle& triangles = myT->Triangles();
164
165 Standard_Integer nnn = myT->NbTriangles(); // nnn : nombre de triangles
166 Standard_Integer nt, n1, n2, n3 = 0;// nt : triangle courant
167 // ni : sommet i du triangle courant
168 //recherche du pt "haut" et du pt "bas
169 for (nt = 1; nt <= nnn; nt++)
170 {
171 // triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
172
9a148b08 173 if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
5c1f974e 174 triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
175 else
176 triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
177
178 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
179 { // Associates a vertexNT to each node
180 gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
181 gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
182 gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
183
184 if (p.Z() > H.Z()) H=p;
185 if (q.Z() > H.Z()) H=q;
186 if (r.Z() > H.Z()) H=r;
187 if (p.Z() < B.Z()) B=p;
188 if (q.Z() < B.Z()) B=q;
189 if (r.Z() < B.Z()) B=r;
190 }
191 }
192 }
193
194 //khr <--
195
196
197 for( NumFace=0,ExpFace.Init(myShape,TopAbs_FACE); ExpFace.More(); ExpFace.Next(),NumFace++ )
198 {
199 TopoDS_Face myFace = TopoDS::Face(ExpFace.Current());
200 TopLoc_Location myLocation = myFace.Location();
7fd59977 201
202#ifdef DEBUG
5c1f974e 203 cout << "J\'explore actuellement la face " << NumFace << "\n" << endl;
7fd59977 204#endif
5c1f974e 205 Handle(Poly_Triangulation) myT = BRep_Tool::Triangulation(myFace, myLocation);
206 // Returns the Triangulation of the face. It is a null handle if there is no triangulation.
7fd59977 207
5c1f974e 208 if (myT.IsNull())
209 {
7fd59977 210#ifdef DEBUG
5c1f974e 211 //cout << "Triangulation of the face "<< i <<" is null \n"<< endl;
7fd59977 212#endif
5c1f974e 213 return;
214 }
215 Poly_Connect pc(myT);
216 const TColgp_Array1OfPnt& Nodes= myT->Nodes();
217 BAR = GProp_PGProps::Barycentre(Nodes);
218
219
5c573e69 220 //const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
5c1f974e 221 const Poly_Array1OfTriangle& triangles = myT->Triangles();
222 TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
223
5ad8c033 224 StdPrs_ToolTriangulatedShape::Normal(myFace, pc, myNormal);
5c1f974e 225 BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax);
226 dUmax = (Umax - Umin);
227 dVmax = (Vmax - Vmin);
228
229 Standard_Integer nnn = myT->NbTriangles(); // nnn : nombre de triangles
230 Standard_Integer nt, n1, n2, n3 = 0;// nt : triangle courant
231 // ni : sommet i du triangle courant
232
233 //recherche du pt "haut" et du pt "bas
234 // gp_Pnt H (0,0,0);
235 // gp_Pnt B (0,0,1000000000);
236
237 for (nt = 1; nt <= nnn; nt++)
238 {
239 // triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
9a148b08 240 if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
5c1f974e 241 triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
242 else
243 triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
244
245 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
246 { // Associates a vertexNT to each node
247 gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
248 gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
249 gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
250 }
251 }
252
253 Handle(Graphic3d_ArrayOfTriangles) aOP = new Graphic3d_ArrayOfTriangles(3 * nnn, 0, Standard_True, Standard_True);
254
255 for (nt = 1; nt <= nnn; nt++)
256 {
7fd59977 257#ifdef DEBUG
5c1f974e 258 cout << "On traite actuellement le triangle : "<< nt <<"\n";
259#endif
9a148b08 260 if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
5c1f974e 261 triangles(nt).Get(n1,n3,n2); // le triangle est n1,n3,n2
262 else
263 triangles(nt).Get(n1,n2,n3); // le triangle est n1,n2,n3
264
265 if (TriangleIsValid (Nodes(n1),Nodes(n2),Nodes(n3)) )
266 { // Associates a vertexNT to each node
267
268 TColgp_Array1OfPnt Points(1,3);
269
270 gp_Pnt p = Nodes(n1).Transformed(myLocation.Transformation());
271 gp_Pnt q = Nodes(n2).Transformed(myLocation.Transformation());
272 gp_Pnt r = Nodes(n3).Transformed(myLocation.Transformation());
273
274 Points(1).SetCoord(p.X(), p.Y(), p.Z());
275 Points(2).SetCoord(q.X(), q.Y(), q.Z());
276 Points(3).SetCoord(r.X(), r.Y(), r.Z());
277
278 aOP->AddVertex(Points(1), myNormal(n1), Color(p,B.Z(),H.Z(),Dlg.Colorization));
279 aOP->AddVertex(Points(2), myNormal(n2), Color(q,B.Z(),H.Z(),Dlg.Colorization));
280 aOP->AddVertex(Points(3), myNormal(n3), Color(r,B.Z(),H.Z(),Dlg.Colorization));
281 } // end of "if the triangle is valid
282 } // end of the "parcours" of the triangles
283
284 Prs3d_Root::CurrentGroup (aPresentation)->AddPrimitiveArray (aOP);
285
286 mygroup->SetGroupPrimitivesAspect(myAspect);
287 }// end of the exploration of the shape in faces
288
289 break;
290 }
291 }
7fd59977 292}
293
92efcf78 294void User_Cylinder::Compute(const Handle(Prs3d_Projector)& aProjector,
295 const Handle(Prs3d_Presentation)& aPresentation)
7fd59977 296{
4208cf18 297 Handle (Prs3d_Drawer) aDefDrawer = GetContext()->DefaultDrawer();
298 if (aDefDrawer->DrawHiddenLine())
299 myDrawer->EnableDrawHiddenLine();
300 else
301 myDrawer->DisableDrawHiddenLine();
5c1f974e 302 StdPrs_HLRPolyShape::Add(aPresentation,myShape,myDrawer,aProjector);
7fd59977 303}
304
92efcf78 305void User_Cylinder::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
5c1f974e 306 const Standard_Integer aMode)
7fd59977 307{
5c1f974e 308 switch(aMode)
309 {
310 case 0:
311 StdSelect_BRepSelectionTool::Load(aSelection,this,myShape,TopAbs_SHAPE, 0.01, 0.1);
312 break;
313 case 4:
314 StdSelect_BRepSelectionTool::Load(aSelection,this,myShape,TopAbs_FACE, 0.01, 0.1);
315 break;
316 }
7fd59977 317}
318
319Standard_Integer User_Cylinder::NbPossibleSelection() const
320{
5c1f974e 321 return 2;
7fd59977 322}
323
324Standard_Boolean User_Cylinder::AcceptShapeDecomposition() const
325{
5c1f974e 326 return Standard_True;
7fd59977 327}
328
7fd59977 329Standard_Boolean User_Cylinder::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
330{
5c1f974e 331 gp_Vec V1(P1,P2);// V1=(P1,P2)
332 gp_Vec V2(P2,P3);// V2=(P2,P3)
333 gp_Vec V3(P3,P1);// V3=(P3,P1)
334
7fd59977 335 if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
5c1f974e 336 {
337 V1.Cross(V2);// V1 = Normal
338 if (V1.SquareMagnitude() > 1.e-10)
339 return Standard_True;
340 else
341 return Standard_False;
342 }
7fd59977 343 else
344 return Standard_False;
7fd59977 345}
346
347Quantity_Color User_Cylinder::Color(gp_Pnt& thePoint,Standard_Real AltMin,Standard_Real AltMax,
5c1f974e 348 const Standard_Integer ColorizationMode)
7fd59977 349{
5c1f974e 350 red =1; //initializing colors parameters
351 green=1;
352 blue =1;
353 switch ( ColorizationMode)
354 {
355 case 0 : //normal, vert/maron
356 {
357 Standard_Real Alt= thePoint.Z();
358
359 Standard_Real AltDelta;
360
361 AltDelta = AltMax-AltMin;
362
363 red = 0.5- ((0.5*(AltMax-Alt))/(AltDelta));
5c573e69 364 //Standard_Real A = 7*Alt-7*AltMin;
5c1f974e 365 green = (3*AltMax-AltMin)/(3*AltMax-AltMin+(7*Alt-7*AltMin));
366 blue = 0 ;
367
368 Quantity_Color color;
369 color.SetValues(red,green,blue, Quantity_TOC_RGB);
370 return color;
371 break;
372 }//end case 0
373
374 case 1 : //mer-neige
375 {
376 Standard_Real Alt= thePoint.Z();
377
378 Standard_Real b =AltMax-AltMin;
379 Standard_Real a= AltMax-thePoint.Z();
380
381 red =1;
382 green=1;
383 blue =1;
384 if (0<a && a <= (b/5))
385 {
386 red = 1;
387 green = 1;
388 blue = 1;
389 }
390 else if ((b/5)<a && a <= (2*b/5))
391 {
392 red = .55;
393 green = 0.3;
394 blue = 0;
395 }
396 else if ((2*b/5)<a && a <= (18*b/20))
397 {
398 green =1/(((7/(3*AltMax-AltMin))*Alt)+(1-(7*AltMin/(3*AltMax-AltMin))));
399 red = 1/(((1000/(AltMax-AltMin))*Alt)+1000*(1-(AltMin/(AltMax-AltMin))));
400 blue = 0;
401 }
402 else if ((18*b/20)<a && a <= (18.5*b/20))
403 {
404 red = 0.75;
405 green = 0.66;
406 blue = 0;
407 }
408
409 else if ((18.5*b/20)<a && a <= b)
410 {
411 red = 0.25;
412 green = .66;
413 blue = 1;
414 }
415 Quantity_Color color;
416 color.SetValues(red,green,blue, Quantity_TOC_RGB);
417 return color;
418 break;
419 }//end case 1
420
421 case 2 :
422 {
423 gp_Pnt P (85.,0.,-105.);
424 gp_Vec TheVect ( P, thePoint);
425 Standard_Real CoordX;
426 Standard_Real CoordY;
427 Standard_Real CoordZ;
428
429 CoordX = TheVect.X();
430 CoordY = TheVect.Y();
431 CoordZ = TheVect.Z();
432
433 Standard_Real Distance = BAR.Distance ( P);
434
435 Standard_Real a =fabs(CoordX);
436 Standard_Real b =fabs(CoordY);
437 Standard_Real c =fabs(CoordZ);
438
439 Standard_Real xx = a / Max(Distance,a); //(Max (Distance, Maxi));
440 Standard_Real yy = b / Max(Distance,b); //(Max (Distance, Maxi));
441 Standard_Real zz = c / Max(Distance,c); //(Max (Distance, Maxi));
442
443
444 if (myXRedOnOff)
445 red = xx;
446 else if (myXGreenOnOff)
447 green =xx;
448 else if (myXBlueOnOff)
449 blue=xx;
450
451 if (myYRedOnOff)
452 red = yy;
453 else if (myYGreenOnOff)
454 green = yy;
455 else if (myYBlueOnOff)
456 blue = yy;
457
458 if (myZRedOnOff)
459 red = zz;
460 else if (myZGreenOnOff)
461 green = zz;
462 else if (myZBlueOnOff)
463 blue = zz;
464 Quantity_Color color;
465 color.SetValues(red,green,blue, Quantity_TOC_RGB);
466 return color;
467 break;
468 }//end case 2
469 }//end switch
470
471 Quantity_Color c;
472 return c;
7fd59977 473}
474
475void User_Cylinder::SetColor(const Quantity_Color &aColor)
476{
5c1f974e 477 AIS_InteractiveObject::SetColor(aColor);
4208cf18 478 myColor = aColor;
7fd59977 479}