DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DGtalInventor.ih
1 
30 
31 #include <cstdlib>
33 
35 // IMPLEMENTATION of inline methods.
37 
39 // ----------------------- Standard services ------------------------------
40 
44 template <typename TSpace>
45 inline
47 {
48 }
49 
53 template <typename TSpace>
54 inline
56  : myLattice()
57 {
58  myLattice.init( Space::dimension, 3 );
59 }
60 
65 template <typename TSpace>
66 inline
67 std::string
68 DGtal::DGtalInventor<TSpace>::getMode( const std::string & objectName ) const
69 {
70  ModeMapping::const_iterator itm = myModes.find( objectName );
71  return itm == myModes.end() ? "" : itm->second;
72 }
73 
81 template <typename TSpace>
82 inline
83 void
85 {
86  ASSERT( l.n() == Space::dimension );
87  myLattice = l;
88 }
89 
90 
95 template <typename TSpace>
96 inline
97 void
99 {
100  myCells[ 0 ].clear();
101  myCells[ 1 ].clear();
102  myCells[ 2 ].clear();
103  myNormals.clear();
104  myColors.clear();
105 }
106 
110 template <typename TSpace>
111 inline
112 void
114 {
115  myDiffuseColor = Color( color );
116 }
117 
121 template <typename TSpace>
122 inline
123 void
125 {
126  myDiffuseColor = color;
127 }
128 
137 template <typename TSpace>
138 inline
139 void
141 ( const Point & c, bool orient, const float* n )
142 {
143  // while cells are "volumic", extracts their boundary.
144  Dimension cdim = 0;
145  for ( typename Point::ConstIterator it = c.begin(); it != c.end(); ++it )
146  if ( *it & 0x1 ) ++cdim;
147  if ( cdim > 2 )
148  {
149  Point p( c );
150  for ( typename Point::Iterator it = p.begin(); it != p.end(); ++it )
151  if ( *it & 0x1 )
152  {
153  --(*it);
154  drawCell( p, false, n );
155  *it += 2;
156  drawCell( p, true, n );
157  --(*it);
158  }
159  }
160  else
161  {
162  myCells[ cdim ].insert( std::make_pair( c, orient ) );
163  myColors[ c ] = myDiffuseColor;
164  if ( n != 0 ) myNormals[ c ] = n;
165  }
166 }
167 
174 template <typename TSpace>
175 inline
176 void
177 DGtal::DGtalInventor<TSpace>::drawPoint( const Point & c, const float* n )
178 {
179  Point q;
180  for ( Dimension i = 0; i < c.dimension; ++i )
181  q[ i ] = 2*c[ i ] + 1;
182  drawCell( q, n );
183 }
184 
186 // Interface - public :
187 
192 template <typename TSpace>
193 inline
194 void
195 DGtal::DGtalInventor<TSpace>::selfDisplay ( std::ostream & out ) const
196 {
197  out << "[DGtalInventor]";
198 }
199 
204 template <typename TSpace>
205 inline
206 bool
208 {
209  return true;
210 }
211 
212 
214 // Inventor methods
215 
216 
223 template <typename TSpace>
224 void
226 {
227  typedef float vec3[ 3 ];
228  typedef DGtal::int32_t int32;
229  typedef DGtal::uint32_t uint32;
230 
231  SoShapeHints *myShapeHints = new SoShapeHints;
232  myShapeHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING;//COUNTERCLOCKWISE; //UNKNOWN_ORDERING; //COUNTERCLOCKWISE;
233  myShapeHints->shapeType =
234  false ? SoShapeHints::SOLID : SoShapeHints::UNKNOWN_SHAPE_TYPE;
235  myShapeHints->faceType = SoShapeHints::CONVEX;
236  myShapeHints->creaseAngle = 1.0;
237  result->addChild( myShapeHints );
238 
239  // some initialization
240  uint32 nb_vtx; // number of vertices to display
241  uint32 nb_cells; // number of cells
242  vec3* coords; // array of vertex coordinates
243  vec3* xyz; // pointer to fill array [coords]
244  SoCoordinate3 *myCoords; // structure to store coordinates
245  typename CellSet::const_iterator ip;
246  typename CellSet::const_iterator ip_end;
247  int32* indices;// for each face, gives the number of vertices
248  vec3* normals;// array of normal vectors
249  vec3* colors; // array of color vectors
250  typename ColorMapping::const_iterator itc;
251  typename NormalMapping::const_iterator itn;
252  int idx;
253 
254  // Taking care of 2-cells
255  nb_cells = myCells[ 2 ].size();
256  nb_vtx = 4 * nb_cells;
257  if ( nb_vtx != 0 )
258  {
259  cout << "2-cells = " << nb_vtx << endl;
260  SoGroup* node_squares = new SoGroup;
261  myCoords = new SoCoordinate3;
262  coords = new vec3[ nb_vtx ];
263  ip = myCells[ 2 ].begin();
264  ip_end = myCells[ 2 ].end();
265  xyz = coords;
266  indices = new int32[ nb_cells ];
267  normals = new vec3[ nb_cells ];
268  colors = new vec3[ nb_cells ];
269  idx = 0;
270  SbVec3f uv1;
271  SbVec3f uv2;
272  SbVec3f n;
273  while ( ip != ip_end )
274  {
275  unsigned int d = 0;
276  Point c = ip->first;
277  bool orient = ip->second;
278  Point e;
279  Dimension dirs[ 2 ];
280  for ( Dimension i = 0; i < c.dimension; ++i )
281  {
282  if ( c[ i ] & 0x1 )
283  dirs[ d++ ] = i;
284  e[ i ] = c[ i ] >> 1;
285  }
286 
287  // creating face coordinates
288  myLattice.immerse( e, *xyz );
289  uv1.setValue( *xyz );
290  uv2.setValue( *xyz );
291  ++xyz;
292  e[ dirs[ 0 ] ] ++;
293  myLattice.immerse( e, *xyz );
294  uv1 -= SbVec3f( *xyz );
295  ++xyz;
296  e[ dirs[ 1 ] ] ++;
297  myLattice.immerse( e, *xyz );
298  ++xyz;
299  e[ dirs[ 0 ] ] --;
300  myLattice.immerse( e, *xyz );
301  uv2 -= SbVec3f( *xyz );
302  ++xyz;
303  indices[ idx ] = 4;
304 
305  // retracts( xyz - 4, 4 );
306 
307  // Creating face normals
308  itn = myNormals.find( c );
309  n = uv1.cross( uv2 );
310  if ( orient )
311  {
312  if ( n[ 0 ] < 0.0 ) n[ 0 ] = -n[ 0 ];
313  if ( n[ 1 ] < 0.0 ) n[ 1 ] = -n[ 1 ];
314  if ( n[ 2 ] < 0.0 ) n[ 2 ] = -n[ 2 ];
315  }
316  else
317  {
318  if ( n[ 0 ] > 0.0 ) n[ 0 ] = -n[ 0 ];
319  if ( n[ 1 ] > 0.0 ) n[ 1 ] = -n[ 1 ];
320  if ( n[ 2 ] > 0.0 ) n[ 2 ] = -n[ 2 ];
321  }
322  if ( itn != myNormals.end() )
323  {
324  n = itn->second;
325  double dot = uv1[0]*n[0]+uv1[1]*n[1]+uv1[2]*n[2];
326  if ( dot < 0.0 )
327  {
328  vec3* xyz1 = xyz - 3;
329  vec3* xyz2 = xyz - 1;
330  std::swap( (*xyz1)[0], (*xyz2)[0] );
331  std::swap( (*xyz1)[1], (*xyz2)[1] );
332  std::swap( (*xyz1)[2], (*xyz2)[2] );
333  }
334  }
335  n.getValue( normals[ idx ][ 0 ],
336  normals[ idx ][ 1 ],
337  normals[ idx ][ 2 ] );
338 
339  // Creating face colors
340  itc = myColors.find( c );
341  if ( itc != myColors.end() )
342  n = itc->second;
343  n.getValue( colors[ idx ][ 0 ],
344  colors[ idx ][ 1 ],
345  colors[ idx ][ 2 ] );
346 
347  ++idx;
348  ++ip;
349  }
350  // Coordinates
351  myCoords->point.setValues( 0, nb_vtx, coords );
352  node_squares->addChild( myCoords );
353 
354  // Normals
355  SoNormal* iNormals = new SoNormal;
356  iNormals->vector.setValues( 0, idx, normals );
357  delete[] normals;
358  node_squares->addChild( iNormals );
359  SoNormalBinding *iNormalBinding = new SoNormalBinding;
360  iNormalBinding->value = SoNormalBinding::PER_FACE;
361  // instead of SoNormalBinding::PER_VERTEX_INDEXED;
362  node_squares->addChild( iNormalBinding );
363 
364  // Colors
365  SoMaterial* iMaterials = new SoMaterial;
366  iMaterials->diffuseColor.setValues( 0, idx, colors );
367  delete[] colors;
368  node_squares->addChild( iMaterials );
369  SoMaterialBinding* iMaterialBinding = new SoMaterialBinding;
370  iMaterialBinding->value = SoMaterialBinding::PER_FACE;
371  node_squares->addChild( iMaterialBinding );
372 
373  // Faces
374  SoFaceSet* face_set = new SoFaceSet;
375  face_set->numVertices.setValues( 0, idx, indices );
376  node_squares->addChild( face_set );
377  result->addChild( node_squares );
378  delete[] indices;
379  }
380 }
381 
382 
384 // Implementation of inline functions //
385 
386 template <typename TSpace>
387 inline
388 std::ostream&
389 DGtal::operator<< ( std::ostream & out,
390  const DGtalInventor<TSpace> & object )
391 {
392  object.selfDisplay( out );
393  return out;
394 }
395 
396 // //
398 
399