0029516: Visualization - eliminate redundant property Graphic3d_MaterialAspect::Refle...
[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
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_ToolTriangulatedShape.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 <Quantity_Color.hxx>
22 #include <BRepMesh_IncrementalMesh.hxx>
23 #include <Prs3d.hxx>
24
25 #include <AIS_GraphicTool.hxx>
26
27 // Constructors implementation
28 //
29
30 User_Cylinder::User_Cylinder(const Standard_Real R, const Standard_Real H) :
31 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
32 {
33   BRepPrimAPI_MakeCylinder S(R,H);
34   myShape = S.Shape();
35   SetHilightMode(0);
36   myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
37   myColor = Quantity_NOC_GRAY;
38 }
39
40 User_Cylinder::User_Cylinder(const gp_Ax2 CylAx2, const Standard_Real R, const Standard_Real H) :
41 AIS_InteractiveObject(PrsMgr_TOP_ProjectorDependant)
42
43 {
44   BRepPrimAPI_MakeCylinder S(CylAx2,R,H);
45   BRepBuilderAPI_NurbsConvert aNurbsConvert(S.Shape());
46   myShape = aNurbsConvert.Shape();
47   SetHilightMode(0);
48   myDrawer->SetShadingAspect(new Prs3d_ShadingAspect());
49   myColor = Quantity_NOC_KHAKI4;
50 }
51
52 void User_Cylinder::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/,
53                             const Handle(Prs3d_Presentation)& aPresentation,
54                             const Standard_Integer aMode ) 
55 {
56   switch (aMode) {
57 case AIS_WireFrame:
58   {
59     StdPrs_WFShape::Add(aPresentation,myShape, myDrawer );
60     break;
61   }
62 case AIS_Shaded:
63   {
64     Standard_Real aTransparency = Transparency();
65     Graphic3d_NameOfMaterial aMaterial = Material();
66     myDrawer->ShadingAspect()->SetMaterial(aMaterial);
67     myDrawer->ShadingAspect()->SetColor(myColor);
68     myDrawer->ShadingAspect()->SetTransparency (aTransparency);
69     StdPrs_ShadedShape::Add(aPresentation,myShape, myDrawer);
70     break;
71   }
72 case 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.SetAmbientColor (Quantity_NOC_BLACK);
83     material.SetDiffuseColor (Quantity_NOC_BLACK);
84     material.SetSpecularColor(Quantity_NOC_BLACK);
85     material.SetEmissiveColor(Quantity_NOC_BLACK);
86     myAspect->SetFrontMaterial(material);
87
88     mygroup->SetPrimitivesAspect(myAspect);
89     myAspect->SetEdgeOn();
90
91     myDeflection = Prs3d::GetDeflection(myShape,myDrawer);
92     BRepMesh_IncrementalMesh(myShape,myDeflection);
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
112     myXBlueOnOff  = Dlg.m_CheckXBlueOnOff  != 0;
113     myXGreenOnOff = Dlg.m_CheckXGreenOnOff != 0;
114     myXRedOnOff   = Dlg.m_CheckXRedOnOff   != 0;
115
116     myY1OnOff = Dlg.Y1OnOff;
117
118     myYBlueOnOff  = Dlg.m_CheckYBlueOnOff  != 0;
119     myYGreenOnOff = Dlg.m_CheckYGreenOnOff != 0;
120     myYRedOnOff   = Dlg.m_CheckYRedOnOff   != 0;
121
122     myZ1OnOff = Dlg.Z1OnOff;
123
124     myZBlueOnOff  = Dlg.m_CheckZBlueOnOff  != 0;
125     myZGreenOnOff = Dlg.m_CheckZGreenOnOff != 0;
126     myZRedOnOff   = Dlg.m_CheckZRedOnOff   != 0;
127
128     // Adds a triangulation of the shape myShape to its topological data structure.
129     // This triangulation is computed with the deflection myDeflection.
130
131 #ifdef DEBUG
132     std::cout <<"Deflection = " << myDeflection << "\n" << std::endl;
133 #endif
134
135     Standard_Integer NumFace;
136     TopExp_Explorer ExpFace;
137
138     //khr -->
139
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();
146
147 #ifdef DEBUG
148       std::cout << "J\'explore actuellement la face " << NumFace << "\n" << std::endl;
149 #endif
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.
152
153       if (myT.IsNull())
154       {
155 #ifdef DEBUG
156         // std::cout << "Triangulation of the face "<< i <<" is null \n"<< std::endl;
157 #endif
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
173         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
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();
201
202 #ifdef DEBUG
203       std::cout << "J\'explore actuellement la face " << NumFace << "\n" << std::endl;
204 #endif
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.
207
208       if (myT.IsNull())
209       {
210 #ifdef DEBUG
211         //std::cout << "Triangulation of the face "<< i <<" is null \n"<< std::endl;
212 #endif
213         return;
214       }
215       Poly_Connect pc(myT);
216       const TColgp_Array1OfPnt& Nodes= myT->Nodes();
217       BAR = GProp_PGProps::Barycentre(Nodes);
218
219
220       //const TColgp_Array1OfPnt2d& UVNodes = myT->UVNodes();
221       const Poly_Array1OfTriangle& triangles = myT->Triangles();
222       TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper());
223
224       StdPrs_ToolTriangulatedShape::Normal(myFace, pc, myNormal);
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
240         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
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       {
257 #ifdef DEBUG
258         std::cout << "On traite actuellement le triangle : "<< nt <<"\n";
259 #endif
260         if (myFace.Orientation() == TopAbs_REVERSED) // si la face est "reversed"
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   }
292 }
293
294 void User_Cylinder::Compute(const Handle(Prs3d_Projector)& aProjector,
295                             const Handle(Prs3d_Presentation)& aPresentation)
296 {
297   Handle (Prs3d_Drawer) aDefDrawer = GetContext()->DefaultDrawer();
298   if (aDefDrawer->DrawHiddenLine())
299     myDrawer->EnableDrawHiddenLine();
300   else
301     myDrawer->DisableDrawHiddenLine();
302   StdPrs_HLRPolyShape::Add(aPresentation,myShape,myDrawer,aProjector);
303 }
304
305 void User_Cylinder::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
306                                     const Standard_Integer aMode)
307 {
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   }
317 }
318
319 Standard_Integer User_Cylinder::NbPossibleSelection() const
320 {
321   return 2;
322 }
323
324 Standard_Boolean User_Cylinder::AcceptShapeDecomposition() const
325 {
326   return Standard_True;
327 }
328
329 Standard_Boolean User_Cylinder::TriangleIsValid(const gp_Pnt& P1, const gp_Pnt& P2, const gp_Pnt& P3) const
330
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
335   if ((V1.SquareMagnitude() > 1.e-10) && (V2.SquareMagnitude() > 1.e-10) && (V3.SquareMagnitude() > 1.e-10))
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   }
343   else
344     return Standard_False;
345 }
346
347 Quantity_Color User_Cylinder::Color(gp_Pnt& thePoint,Standard_Real AltMin,Standard_Real AltMax,
348                                     const Standard_Integer ColorizationMode) 
349 {
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));
364       //Standard_Real A = 7*Alt-7*AltMin;
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;
473 }
474
475 void User_Cylinder::SetColor(const Quantity_Color &aColor)
476 {
477   AIS_InteractiveObject::SetColor(aColor);
478   myColor = aColor;
479 }