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