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