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