1 // Created on: 2003-12-17
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2003-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15 
16 
17 #include <Font_NameOfFont.hxx>
18 #include <gp_Vec.hxx>
19 #include <Graphic3d_AspectFillArea3d.hxx>
20 #include <Graphic3d_AspectLine3d.hxx>
21 #include <Graphic3d_AspectMarker3d.hxx>
22 #include <Graphic3d_AspectText3d.hxx>
23 #include <Graphic3d_MaterialAspect.hxx>
24 #include <MeshVS_Drawer.hxx>
25 #include <MeshVS_DrawerAttribute.hxx>
26 #include <MeshVS_Tool.hxx>
27 #include <Precision.hxx>
28 
29 //================================================================
30 // Function : CreateAspectFillArea3d
31 // Purpose  :
32 //================================================================
Handle(Graphic3d_AspectFillArea3d)33 Handle( Graphic3d_AspectFillArea3d ) MeshVS_Tool::CreateAspectFillArea3d
34 (  const Handle(MeshVS_Drawer)& theDr,
35    const Graphic3d_MaterialAspect& Mat,
36    const Standard_Boolean UseDefaults )
37 {
38   Handle( Graphic3d_AspectFillArea3d ) anAsp;
39   if ( theDr.IsNull() )
40     return anAsp;
41 
42   Aspect_InteriorStyle     anIntStyle    = Aspect_IS_EMPTY;
43   Quantity_Color           anIntColor    = Quantity_NOC_CYAN1,
44                            anEdgeColor   = Quantity_NOC_WHITE;
45   Aspect_TypeOfLine        anEdgeType    = Aspect_TOL_SOLID;
46   Standard_Real            anEdgeWidth   = 1.0;
47   Aspect_HatchStyle        aHStyle       = Aspect_HS_HORIZONTAL;
48   Graphic3d_MaterialAspect aFrMat        = Mat,
49                            aBackMat      = Mat;
50 
51   Standard_Integer         anIntStyleI   = (Standard_Integer)Aspect_IS_EMPTY;
52   Standard_Integer         anEdgeTypeI   = (Standard_Integer)Aspect_TOL_SOLID;
53   Standard_Integer         aHStyleI      = (Standard_Integer)Aspect_HS_HORIZONTAL;
54 
55   if ( !theDr->GetColor ( MeshVS_DA_InteriorColor, anIntColor ) && !UseDefaults )
56     return anAsp;
57 
58   Quantity_Color aBackIntColor = anIntColor;
59   if ( !theDr->GetColor ( MeshVS_DA_BackInteriorColor, aBackIntColor ) && !UseDefaults )
60     return anAsp;
61 
62   if ( !theDr->GetColor ( MeshVS_DA_EdgeColor, anEdgeColor ) && !UseDefaults )
63     return anAsp;
64 
65   if ( !theDr->GetDouble ( MeshVS_DA_EdgeWidth, anEdgeWidth ) && !UseDefaults )
66     return anAsp;
67 
68   if ( !theDr->GetInteger ( MeshVS_DA_InteriorStyle, anIntStyleI ) && !UseDefaults )
69     return anAsp;
70   else
71     anIntStyle = (Aspect_InteriorStyle) anIntStyleI;
72 
73   if ( !theDr->GetInteger ( MeshVS_DA_EdgeType, anEdgeTypeI ) && !UseDefaults )
74     return anAsp;
75   else
76     anEdgeType = (Aspect_TypeOfLine) anEdgeTypeI;
77 
78   if ( !theDr->GetInteger ( MeshVS_DA_HatchStyle, aHStyleI ) && !UseDefaults )
79     return anAsp;
80   else
81     aHStyle = (Aspect_HatchStyle) aHStyleI;
82 
83   anAsp = new Graphic3d_AspectFillArea3d ( anIntStyle, anIntColor, anEdgeColor, anEdgeType,
84     anEdgeWidth, aFrMat, aBackMat );
85   anAsp->SetBackInteriorColor ( aBackIntColor );
86   anAsp->SetHatchStyle ( aHStyle );
87 
88   return anAsp;
89 }
90 
91 //================================================================
92 // Function : CreateAspectFillArea3d
93 // Purpose  :
94 //================================================================
Handle(Graphic3d_AspectFillArea3d)95 Handle( Graphic3d_AspectFillArea3d ) MeshVS_Tool::CreateAspectFillArea3d
96 (  const Handle(MeshVS_Drawer)& theDr,
97    const Standard_Boolean UseDefaults )
98 {
99   Graphic3d_MaterialAspect aFrMat   = Graphic3d_NameOfMaterial_Brass;
100   Graphic3d_MaterialAspect aBackMat = Graphic3d_NameOfMaterial_Brass;
101   Standard_Integer aFrMatI   = (Standard_Integer)Graphic3d_NameOfMaterial_Brass;
102   Standard_Integer aBackMatI = (Standard_Integer)Graphic3d_NameOfMaterial_Brass;
103 
104   if ( !theDr->GetInteger ( MeshVS_DA_FrontMaterial, aFrMatI ) && !UseDefaults )
105     return 0;
106   else
107     aFrMat = (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aFrMatI;
108 
109   if ( !theDr->GetInteger ( MeshVS_DA_BackMaterial, aBackMatI ) && !UseDefaults )
110     return 0;
111   else
112     aBackMat = (Graphic3d_MaterialAspect)(Graphic3d_NameOfMaterial)aBackMatI;
113 
114   Handle( Graphic3d_AspectFillArea3d ) aFill =
115     CreateAspectFillArea3d ( theDr, aFrMat, UseDefaults );
116   aFill->SetBackMaterial ( aBackMat );
117 
118   return aFill;
119 }
120 //================================================================
121 // Function : CreateAspectLine3d
122 // Purpose  :
123 //================================================================
Handle(Graphic3d_AspectLine3d)124 Handle( Graphic3d_AspectLine3d ) MeshVS_Tool::CreateAspectLine3d
125 (  const Handle(MeshVS_Drawer)& theDr,
126  const Standard_Boolean UseDefaults )
127 {
128   Handle( Graphic3d_AspectLine3d ) anAsp;
129   if ( theDr.IsNull() )
130     return anAsp;
131 
132   Quantity_Color           aBeamColor   = Quantity_NOC_YELLOW;
133   Aspect_TypeOfLine        aBeamType    = Aspect_TOL_SOLID;
134   Standard_Real            aBeamWidth   = 1.0;
135   Standard_Integer         aBeamTypeI   = (Standard_Integer)Aspect_TOL_SOLID;
136 
137   if ( !theDr->GetColor ( MeshVS_DA_BeamColor, aBeamColor ) && !UseDefaults )
138     return anAsp;
139 
140   if ( !theDr->GetDouble ( MeshVS_DA_BeamWidth, aBeamWidth ) && !UseDefaults )
141     return anAsp;
142 
143   if ( !theDr->GetInteger ( MeshVS_DA_BeamType, aBeamTypeI ) && !UseDefaults )
144     return anAsp;
145   else
146     aBeamType = (Aspect_TypeOfLine) aBeamTypeI;
147 
148   anAsp = new Graphic3d_AspectLine3d ( aBeamColor, aBeamType, aBeamWidth );
149 
150   return anAsp;
151 }
152 
153 //================================================================
154 // Function : CreateAspectMarker3d
155 // Purpose  :
156 //================================================================
Handle(Graphic3d_AspectMarker3d)157 Handle( Graphic3d_AspectMarker3d ) MeshVS_Tool::CreateAspectMarker3d
158 (  const Handle(MeshVS_Drawer)& theDr,
159  const Standard_Boolean UseDefaults )
160 {
161   Handle( Graphic3d_AspectMarker3d ) anAsp;
162   if ( theDr.IsNull() )
163     return anAsp;
164 
165   Quantity_Color           aMColor   = Quantity_NOC_YELLOW;
166   Aspect_TypeOfMarker      aMType    = Aspect_TOM_X;
167   Standard_Real            aMScale   = 1.0;
168   Standard_Integer         aMTypeI   = (Standard_Integer)Aspect_TOM_X;
169 
170   if ( !theDr->GetColor ( MeshVS_DA_MarkerColor, aMColor ) && !UseDefaults )
171     return anAsp;
172 
173   if ( !theDr->GetDouble ( MeshVS_DA_MarkerScale, aMScale ) && !UseDefaults )
174     return anAsp;
175 
176   if ( !theDr->GetInteger ( MeshVS_DA_MarkerType, aMTypeI ) && !UseDefaults )
177     return anAsp;
178   else
179     aMType = (Aspect_TypeOfMarker) aMTypeI;
180 
181   anAsp = new Graphic3d_AspectMarker3d ( aMType, aMColor, aMScale );
182 
183   return anAsp;
184 }
185 
186 //================================================================
187 // Function : CreateAspectText3d
188 // Purpose  :
189 //================================================================
Handle(Graphic3d_AspectText3d)190 Handle( Graphic3d_AspectText3d ) MeshVS_Tool::CreateAspectText3d
191 (  const Handle(MeshVS_Drawer)& theDr,
192    const Standard_Boolean UseDefaults )
193 {
194   Handle( Graphic3d_AspectText3d ) anAsp;
195   if ( theDr.IsNull() )
196     return anAsp;
197 
198   Quantity_Color            aTColor       = Quantity_NOC_YELLOW;
199   Standard_Real             anExpFactor   = 1.0,
200                             aSpace        = 0.0;
201   Standard_CString          aFont         = Font_NOF_ASCII_MONO;
202   Aspect_TypeOfStyleText    aStyle        = Aspect_TOST_NORMAL;
203   Aspect_TypeOfDisplayText  aDispText     = Aspect_TODT_NORMAL;
204   TCollection_AsciiString   aFontString   = Font_NOF_ASCII_MONO;
205   Font_FontAspect           aFontAspect   = Font_FA_Regular;
206   Standard_Integer          aStyleI       = (Standard_Integer)Aspect_TOST_NORMAL;
207   Standard_Integer          aDispTextI    = (Standard_Integer)Aspect_TODT_NORMAL;
208   // Bold font is used by default for better text readability
209   Standard_Integer          aFontAspectI  = (Standard_Integer)Font_FA_Bold;
210 
211   if ( !theDr->GetColor ( MeshVS_DA_TextColor, aTColor ) && !UseDefaults )
212     return anAsp;
213 
214   if ( !theDr->GetDouble ( MeshVS_DA_TextExpansionFactor, anExpFactor ) && !UseDefaults )
215     return anAsp;
216 
217   if ( !theDr->GetDouble ( MeshVS_DA_TextSpace, aSpace ) && !UseDefaults )
218     return anAsp;
219 
220   if ( !theDr->GetAsciiString ( MeshVS_DA_TextFont, aFontString ) && !UseDefaults )
221     return anAsp;
222   else
223     aFont = aFontString.ToCString();
224 
225   if ( !theDr->GetInteger ( MeshVS_DA_TextStyle, aStyleI ) && !UseDefaults )
226     return anAsp;
227   else
228     aStyle = (Aspect_TypeOfStyleText) aStyleI;
229 
230   if ( !theDr->GetInteger ( MeshVS_DA_TextDisplayType, aDispTextI ) && !UseDefaults )
231     return anAsp;
232   else
233     aDispText = (Aspect_TypeOfDisplayText) aDispTextI;
234 
235   if ( !theDr->GetInteger ( MeshVS_DA_TextFontAspect, aFontAspectI ) && !UseDefaults )
236     return anAsp;
237   else
238     aFontAspect = (Font_FontAspect) aFontAspectI;
239 
240   anAsp = new Graphic3d_AspectText3d ( aTColor, aFont, anExpFactor, aSpace, aStyle, aDispText );
241   anAsp->SetTextFontAspect( aFontAspect );
242   return anAsp;
243 }
244 
245 //================================================================
246 // Function : GetNormal
247 // Purpose  :
248 //================================================================
GetNormal(const TColStd_Array1OfReal & Nodes,gp_Vec & Norm)249 Standard_Boolean MeshVS_Tool::GetNormal( const TColStd_Array1OfReal& Nodes,
250                                         gp_Vec& Norm )
251 {
252   Standard_Integer first = Nodes.Lower(),
253     last  = Nodes.Upper(),
254     count = (last-first+1)/3, i, j;
255   if( first==0 )
256   {
257     first = 1;
258     count = Standard_Integer( Nodes.Value( 0 ) );
259   }
260 
261   if( count<3 )
262     return Standard_False;
263 
264   Standard_Boolean res = Standard_True;
265 
266 
267   Standard_Real normal[3], first_vec[3], cur_vec[3], xx, yy, zz,
268     conf = Precision::Confusion();
269 
270   for( i=0; i<3; i++ )
271   {
272     normal[i] = 0.0;
273     first_vec[i] = Nodes.Value( first+3+i ) - Nodes.Value( first+i );
274   }
275 
276   for( i=2; i<count; i++ )
277   {
278     for( j=0; j<3; j++ )
279       cur_vec[j] = Nodes.Value( first+3*i+j ) - Nodes.Value( first+j );
280 
281     xx = first_vec[1] * cur_vec[2] - first_vec[2] * cur_vec[1];
282     yy = first_vec[2] * cur_vec[0] - first_vec[0] * cur_vec[2];
283     zz = first_vec[0] * cur_vec[1] - first_vec[1] * cur_vec[0];
284 
285     cur_vec[0] = xx;
286     cur_vec[1] = yy;
287     cur_vec[2] = zz;
288 
289     if( fabs( cur_vec[0] ) > conf ||
290       fabs( cur_vec[1] ) > conf ||
291       fabs( cur_vec[2] ) > conf )
292     {
293       Standard_Real cur = Sqrt( cur_vec[0]*cur_vec[0] + cur_vec[1]*cur_vec[1] + cur_vec[2]*cur_vec[2] );
294       for( Standard_Integer k=0; k<3; k++ )
295         cur_vec[k] /= cur;
296     }
297 
298     if( fabs( normal[0] ) <= conf &&
299       fabs( normal[1] ) <= conf &&
300       fabs( normal[2] ) <= conf )
301       for( Standard_Integer k=0; k<3; k++ )
302         normal[k] = cur_vec[k];
303 
304     if( fabs( normal[0]-cur_vec[0] ) > conf ||
305       fabs( normal[1]-cur_vec[1] ) > conf ||
306       fabs( normal[2]-cur_vec[2] ) > conf    )
307     {
308       res = Standard_False;
309       break;
310     }
311   }
312 
313   if( res )
314     Norm.SetCoord( normal[0], normal[1], normal[2] );
315 
316   return res;
317 }
318 
319 
320 //================================================================
321 // Function : GetAverageNormal
322 // Purpose  :
323 //================================================================
GetAverageNormal(const TColStd_Array1OfReal & Nodes,gp_Vec & Norm)324 Standard_Boolean MeshVS_Tool::GetAverageNormal( const TColStd_Array1OfReal& Nodes,
325                                                gp_Vec& Norm )
326 {
327   Standard_Integer first = Nodes.Lower(),
328     last  = Nodes.Upper(),
329     count = (last-first+1)/3, i, j;
330   if( first==0 )
331   {
332     first = 1;
333     count = Standard_Integer( Nodes.Value( 0 ) );
334   }
335 
336   if( count<3 )
337     return Standard_False;
338 
339   Standard_Boolean res = Standard_True;
340 
341 
342   Standard_Real normal[3], first_vec[3], cur_vec[3], xx, yy, zz,
343     conf = Precision::Confusion();
344 
345   for( i=0; i<3; i++ )
346   {
347     normal[i] = 0.0;
348     first_vec[i] = Nodes.Value( first+3+i ) - Nodes.Value( first+i );
349   }
350 
351   gp_XYZ* norm_vec = new gp_XYZ[count-2];
352   for ( i = 0; i < count-2; i++ )
353     norm_vec[i].SetCoord(0, 0, 0);
354 
355   for( i=2; i<count; i++ )
356   {
357     for( j=0; j<3; j++ )
358       cur_vec[j] = Nodes.Value( first+3*i+j ) - Nodes.Value( first+j );
359 
360     xx = first_vec[1] * cur_vec[2] - first_vec[2] * cur_vec[1];
361     yy = first_vec[2] * cur_vec[0] - first_vec[0] * cur_vec[2];
362     zz = first_vec[0] * cur_vec[1] - first_vec[1] * cur_vec[0];
363 
364     cur_vec[0] = xx;
365     cur_vec[1] = yy;
366     cur_vec[2] = zz;
367 
368     if( fabs( cur_vec[0] ) > conf ||
369       fabs( cur_vec[1] ) > conf ||
370       fabs( cur_vec[2] ) > conf )
371     {
372       Standard_Real cur = Sqrt( cur_vec[0]*cur_vec[0] + cur_vec[1]*cur_vec[1] + cur_vec[2]*cur_vec[2] );
373       for( Standard_Integer k=0; k<3; k++ )
374         cur_vec[k] /= cur;
375     }
376 
377     norm_vec[i-2].SetCoord(cur_vec[0], cur_vec[1], cur_vec[2]);
378 
379     if( fabs( normal[0] ) <= conf &&
380       fabs( normal[1] ) <= conf &&
381       fabs( normal[2] ) <= conf )
382       for( Standard_Integer k=0; k<3; k++ )
383         normal[k] = cur_vec[k];
384 
385     if( fabs( normal[0]-cur_vec[0] ) > conf ||
386       fabs( normal[1]-cur_vec[1] ) > conf ||
387       fabs( normal[2]-cur_vec[2] ) > conf    )
388     {
389       res = Standard_False;
390     }
391   }
392 
393   if( !res ) {
394     for( j=0; j<3; j++ ) {
395       normal[j] = 0.0;
396       for (i = 0; i < count-2; i++)
397         normal[j] += norm_vec[i].Coord(j+1);
398       normal[j] /= (count-2);
399     }
400   }
401   delete [] norm_vec;
402 
403   Norm.SetCoord( normal[0], normal[1], normal[2] );
404 
405   return res;
406 }
407