0031642: Visualization - crash in Graphic3d_Structure::SetVisual() on redisplaying...
[occt.git] / src / XSDRAWSTLVRML / XSDRAWSTLVRML_DataSource.cxx
1 // Created on: 2004-06-10
2 // Created by: Alexander SOLOVYOV
3 // Copyright (c) 2004-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 #include <XSDRAWSTLVRML_DataSource.hxx>
17
18 #include <Precision.hxx>
19 #include <Standard_Type.hxx>
20 #include <TColgp_SequenceOfXYZ.hxx>
21 #include <TColStd_DataMapOfIntegerInteger.hxx>
22 #include <TColStd_DataMapOfIntegerReal.hxx>
23
24 IMPLEMENT_STANDARD_RTTIEXT(XSDRAWSTLVRML_DataSource,MeshVS_DataSource)
25
26 //================================================================
27 // Function : Constructor
28 // Purpose  :
29 //================================================================
30 XSDRAWSTLVRML_DataSource::XSDRAWSTLVRML_DataSource (const Handle(Poly_Triangulation)& aMesh)
31 {
32   myMesh = aMesh;
33
34   if( !myMesh.IsNull() )
35   {
36     const TColgp_Array1OfPnt& aCoords = myMesh->Nodes();
37     Standard_Integer len = aCoords.Length(), i, j;
38     myNodeCoords = new TColStd_HArray2OfReal(1, len, 1, 3);
39     std::cout << "Nodes : " << len << std::endl;
40
41     gp_XYZ xyz;
42
43     for( i = 1; i <= len; i++ )
44     {
45       myNodes.Add( i );
46       xyz = aCoords(i).XYZ();
47
48       myNodeCoords->SetValue(i, 1, xyz.X());
49       myNodeCoords->SetValue(i, 2, xyz.Y());
50       myNodeCoords->SetValue(i, 3, xyz.Z());
51     }
52
53     const Poly_Array1OfTriangle& aSeq = myMesh->Triangles();
54     len = aSeq.Length();
55     myElemNormals = new TColStd_HArray2OfReal(1, len, 1, 3);
56     myElemNodes = new TColStd_HArray2OfInteger(1, len, 1, 3);
57
58     std::cout << "Elements : " << len << std::endl;
59
60     for( i = 1; i <= len; i++ )
61     {
62       myElements.Add( i );
63
64       const Poly_Triangle& aTri = aSeq(i);
65
66       Standard_Integer V[3];
67       aTri.Get (V[0], V[1], V[2]);
68
69       const gp_Pnt aP1 = aCoords (V[0]);
70       const gp_Pnt aP2 = aCoords (V[1]);
71       const gp_Pnt aP3 = aCoords (V[2]);
72
73       gp_Vec aV1(aP1, aP2);
74       gp_Vec aV2(aP2, aP3);
75
76       gp_Vec aN = aV1.Crossed(aV2);
77       if (aN.SquareMagnitude() > Precision::SquareConfusion())
78         aN.Normalize();
79       else
80         aN.SetCoord(0.0, 0.0, 0.0);
81
82       for( j = 0; j < 3; j++ )
83       {
84         myElemNodes->SetValue(i, j+1, V[j]);
85       }
86
87       myElemNormals->SetValue (i, 1, aN.X());
88       myElemNormals->SetValue (i, 2, aN.Y());
89       myElemNormals->SetValue (i, 3, aN.Z());
90     }
91   }
92   std::cout << "Construction is finished" << std::endl;
93 }
94
95 //================================================================
96 // Function : GetGeom
97 // Purpose  :
98 //================================================================
99 Standard_Boolean XSDRAWSTLVRML_DataSource::GetGeom
100 ( const Standard_Integer ID, const Standard_Boolean IsElement,
101  TColStd_Array1OfReal& Coords, Standard_Integer& NbNodes,
102  MeshVS_EntityType& Type ) const
103 {
104   if( myMesh.IsNull() )
105     return Standard_False;
106
107   if( IsElement )
108   {
109     if( ID>=1 && ID<=myElements.Extent() )
110     {
111       Type = MeshVS_ET_Face;
112       NbNodes = 3;
113
114       for( Standard_Integer i = 1, k = 1; i <= 3; i++ )
115       {
116         Standard_Integer IdxNode = myElemNodes->Value(ID, i);
117         for(Standard_Integer j = 1; j <= 3; j++, k++ )
118           Coords(k) = myNodeCoords->Value(IdxNode, j);
119       }
120
121       return Standard_True;
122     }
123     else
124       return Standard_False;
125   }
126   else
127     if( ID>=1 && ID<=myNodes.Extent() )
128     {
129       Type = MeshVS_ET_Node;
130       NbNodes = 1;
131
132       Coords( 1 ) = myNodeCoords->Value(ID, 1);
133       Coords( 2 ) = myNodeCoords->Value(ID, 2);
134       Coords( 3 ) = myNodeCoords->Value(ID, 3);
135       return Standard_True;
136     }
137     else
138       return Standard_False;
139 }
140
141 //================================================================
142 // Function : GetGeomType
143 // Purpose  :
144 //================================================================
145 Standard_Boolean XSDRAWSTLVRML_DataSource::GetGeomType
146 ( const Standard_Integer,
147  const Standard_Boolean IsElement,
148  MeshVS_EntityType& Type ) const
149 {
150   if( IsElement )
151   {
152     Type = MeshVS_ET_Face;
153     return Standard_True;
154   }
155   else
156   {
157     Type = MeshVS_ET_Node;
158     return Standard_True;
159   }
160 }
161
162 //================================================================
163 // Function : GetAddr
164 // Purpose  :
165 //================================================================
166 Standard_Address XSDRAWSTLVRML_DataSource::GetAddr
167 ( const Standard_Integer, const Standard_Boolean ) const
168 {
169   return NULL;
170 }
171
172 //================================================================
173 // Function : GetNodesByElement
174 // Purpose  :
175 //================================================================
176 Standard_Boolean XSDRAWSTLVRML_DataSource::GetNodesByElement
177 ( const Standard_Integer ID,
178  TColStd_Array1OfInteger& theNodeIDs,
179  Standard_Integer& /*theNbNodes*/ ) const
180 {
181   if( myMesh.IsNull() )
182     return Standard_False;
183
184   if( ID>=1 && ID<=myElements.Extent() && theNodeIDs.Length() >= 3 )
185   {
186     Standard_Integer aLow = theNodeIDs.Lower();
187     theNodeIDs (aLow)     = myElemNodes->Value(ID, 1 );
188     theNodeIDs (aLow + 1) = myElemNodes->Value(ID, 2 );
189     theNodeIDs (aLow + 2) = myElemNodes->Value(ID, 3 );
190     return Standard_True;
191   }
192   return Standard_False;
193 }
194
195 //================================================================
196 // Function : GetAllNodes
197 // Purpose  :
198 //================================================================
199 const TColStd_PackedMapOfInteger& XSDRAWSTLVRML_DataSource::GetAllNodes() const
200 {
201   return myNodes;
202 }
203
204 //================================================================
205 // Function : GetAllElements
206 // Purpose  :
207 //================================================================
208 const TColStd_PackedMapOfInteger& XSDRAWSTLVRML_DataSource::GetAllElements() const
209 {
210   return myElements;
211 }
212
213 //================================================================
214 // Function : GetNormal
215 // Purpose  :
216 //================================================================
217 Standard_Boolean XSDRAWSTLVRML_DataSource::GetNormal
218 ( const Standard_Integer Id, const Standard_Integer Max,
219  Standard_Real& nx, Standard_Real& ny,Standard_Real& nz ) const
220 {
221   if( myMesh.IsNull() )
222     return Standard_False;
223
224   if( Id>=1 && Id<=myElements.Extent() && Max>=3 )
225   {
226     nx = myElemNormals->Value(Id, 1);
227     ny = myElemNormals->Value(Id, 2);
228     nz = myElemNormals->Value(Id, 3);
229     return Standard_True;
230   }
231   else
232     return Standard_False;
233 }
234