Point Cloud Library (PCL)  1.10.0-dev
opennurbs_texture_mapping.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // defines ON_TextureMapping
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_TEXTURE_MAPPING_INC_)
24 #define OPENNURBS_TEXTURE_MAPPING_INC_
25 
26 ///////////////////////////////////////////////////////////////////////////////
27 //
28 // Class ON_TextureMapping
29 //
30 class ON_Line;
31 class ON_BrepFace;
32 class ON_3dPoint;
33 
34 typedef int ( *TEXMAP_INTERSECT_LINE_SURFACE )( const ON_Line*, const ON_BrepFace*, ON_SimpleArray<ON_X_EVENT>& );
35 typedef bool ( *TEXMAP_BREP_FACE_CLOSEST_POINT )( const ON_BrepFace*, const ON_3dPoint*, ON_3dPoint& );
36 
37 class ON_CLASS ON_TextureMapping : public ON_Object
38 {
39 public:
40  ON_OBJECT_DECLARE(ON_TextureMapping);
41 
44 
45  // The copy constructor and operator= overrides are needed
46  // to ensure m_geometry is properly copied.
49 
50  // overrides virtual ON_Object::IsValid
51  ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
52 
53  // overrides virtual ON_Object::Dump
54  void Dump( ON_TextLog& ) const;
55 
56  // overrides virtual ON_Object::SizeOf
57  unsigned int SizeOf() const;
58 
59  // overrides virtual ON_Object::Write
60  ON_BOOL32 Write(
61  ON_BinaryArchive& binary_archive
62  ) const;
63 
64  // overrides virtual ON_Object::Read
65  ON_BOOL32 Read(
66  ON_BinaryArchive& binary_archive
67  );
68 
69  void Default();
70 
71  virtual
72  ON_UUID ModelObjectId() const;
73 
74  /*
75  Determines whether the mapping, as currently set up, requires vertex normals to be present on the
76  mesh in order to evaluate the mapping correctly.
77  */
78  bool RequiresVertexNormals() const;
79  bool IsPeriodic(void) const;
80 
81  /*
82  Description:
83  Create a mapping that will convert surface parameters into
84  normalized (0,1)x(0,1) texture coordinates.
85  */
86  bool SetSurfaceParameterMapping(void);
87 
88  /*
89  Description:
90  Create a planar projection texture mapping.
91  Parameters:
92  plane - [in]
93  dx - [in] portion of the plane's x axis that is mapped to [0,1]
94  (can be a decreasing interval)
95  dy - [in] portion of the plane's x axis that is mapped to [0,1]
96  (can be a decreasing interval)
97  dz - [in] portion of the plane's x axis that is mapped to [0,1]
98  (can be a decreasing interval)
99  projection_method - [in]
100  1: Closest point mapping.
101  A target point P is mapped to the point on the plane
102  that is closest to P. The target normal is ignored.
103  2: Target line mapping. A target point-vector pair
104  (P, N), are mapped to the point on the plane
105  where the line through P, parallel to N, intersects
106  the plane. If the line is parallel to the plane,
107  the closest point mapping is used.
108  Example:
109  Create a mapping that maps the world axis aligned rectangle in
110  the world yz plane with corners at (0,3,5) and (0,7,19) to the
111  texture coordinate unit square.
112 
113  ON_3dVector plane_xaxis(0.0,1.0,0.0);
114  ON_3dVector plane_yaxis(0.0,0,0,1.0);
115  ON_3dPoint plane_origin(0.0,2.0,4.0);
116  ON_Plane plane(plane_origin,plane_xaxis,plane_yaxis);
117  ON_Interval dx( 0.0, 7.0 - 3.0);
118  ON_Interval dy( 0.0, 19.0 - 5.0);
119  ON_Interval dz( 0.0, 1.0 );
120  ON_TextureMapping mapping;
121  mapping.CreatePlaneMapping(plane,dx,dy,dz);
122 
123  Returns:
124  True if input is valid.
125  */
126  bool SetPlaneMapping(
127  const ON_Plane& plane,
128  const ON_Interval& dx,
129  const ON_Interval& dy,
130  const ON_Interval& dz
131  );
132 
133  /*
134  Description:
135  Create a cylindrical projection texture mapping.
136  Parameters:
137  cylinder - [in]
138  cylinder in world space used to define a cylindrical
139  coordinate system. The angular parameter maps (0,2pi)
140  to texture "u" (0,1), The height parameter maps
141  (height[0],height[1]) to texture "v" (0,1), and
142  the radial parameter maps (0,r) to texture "w" (0,1).
143  bIsCapped - [in]
144  If true, the cylinder is treated as a finite
145  capped cylinder.
146  Returns:
147  True if input is valid.
148  Remarks:
149  When the cylinder is capped and m_texture_space = divided,
150  the cylinder is mapped to texture space as follows:
151  The side is mapped to 0 <= "u" <= 2/3.
152  The bottom is mapped to 2/3 <= "u" <= 5/6.
153  The top is mapped to 5/6 <= "u" <= 5/6.
154  This is the same convention box mapping uses.
155  */
156  bool SetCylinderMapping(
157  const ON_Cylinder& cylinder,
158  bool bIsCapped
159  );
160 
161  /*
162  Description:
163  Create a spherical projection texture mapping.
164  Parameters:
165  sphere - [in]
166  sphere in world space used to define a spherical
167  coordinate system. The longitude parameter maps
168  (0,2pi) to texture "u" (0,1). The latitude paramter
169  maps (-pi/2,+pi/2) to texture "v" (0,1).
170  The radial parameter maps (0,r) to texture "w" (0,1).
171  Returns:
172  True if input is valid.
173  */
174  bool SetSphereMapping(
175  const ON_Sphere& sphere
176  );
177 
178  /*
179  Description:
180  Create a box projection texture mapping.
181  Parameters:
182  plane - [in]
183  The sides of the box the box are parallel to the
184  plane's coordinate planes. The dx, dy, dz intervals
185  determine the location of the sides.
186  dx - [in]
187  Determines the location of the front and back planes.
188  The vector plane.xaxis is perpendicular to these planes
189  and they pass through plane.PointAt(dx[0],0,0) and
190  plane.PointAt(dx[1],0,0), respectivly.
191  dy - [in]
192  Determines the location of the left and right planes.
193  The vector plane.yaxis is perpendicular to these planes
194  and they pass through plane.PointAt(0,dy[0],0) and
195  plane.PointAt(0,dy[1],0), respectivly.
196  dz - [in]
197  Determines the location of the top and bottom planes.
198  The vector plane.zaxis is perpendicular to these planes
199  and they pass through plane.PointAt(0,0,dz[0]) and
200  plane.PointAt(0,0,dz[1]), respectivly.
201  bIsCapped - [in]
202  If true, the box is treated as a finite
203  capped box.
204  Returns:
205  True if input is valid.
206  Remarks:
207  When m_texture_space = divided, the box is mapped to texture
208  space as follows:
209 
210  If the box is not capped, then each side maps to 1/4 of the texture map.
211 
212  v=1+---------+---------+---------+---------+
213  | x=dx[1] | y=dy[1] | x=dx[0] | y=dy[0] |
214  | Front | Right | Back | Left |
215  | --y-> | <-x-- | <-y-- | --x-> |
216  v=0+---------+---------+---------+---------+
217  0/4 <=u<= 1/4 <=u<= 2/4 <=u<= 3/4 <=u<= 4/4
218 
219  If the box is capped, then each side and cap gets 1/6 of the texture map.
220 
221  v=1+---------+---------+---------+---------+---------+---------+
222  | x=dx[1] | y=dy[1] | x=dx[0] | y=dy[0] | z=dx[1] | z=dz[0] |
223  | Front | Right | Back | Left | Top | Bottom |
224  | --y-> | <-x-- | <-y-- | --x-> | --x-> | --x-> |
225  v=0+---------+---------+---------+---------+---------+---------+
226  0/6 <=u<= 1/6 <=u<= 2/6 <=u<= 3/6 <=u<= 4/6 <=u<= 5/6 <=u<= 6/6
227  */
228  bool SetBoxMapping(
229  const ON_Plane& plane,
230  ON_Interval dx,
231  ON_Interval dy,
232  ON_Interval dz,
233  bool bIsCapped
234  );
235 
236  /*
237  Description:
238  Get plane mapping parameters from this texture mapping.
239  Parameters:
240  plane - [out]
241  dx - [out]
242  Portion of the plane's x axis that is mapped to [0,1]
243  dy - [out]
244  Portion of the plane's y axis that is mapped to [0,1]
245  dz - [out]
246  Portion of the plane's z axis that is mapped to [0,1]
247  Returns:
248  True if valid plane mapping parameters were returned.
249  Remarks:
250  NOTE WELL:
251  Generally, GetMappingPlane will not return the same
252  parameters passed to SetPlaneMapping. However, the
253  location of the plane will be the same.
254  */
255  bool GetMappingPlane(
256  ON_Plane& plane,
257  ON_Interval& dx,
258  ON_Interval& dy,
259  ON_Interval& dz
260  ) const;
261 
262  /*
263  Description:
264  Get a cylindrical projection parameters from this texture mapping.
265  Parameters:
266  cylinder - [out]
267  Returns:
268  True if a valid cylinder is returned.
269  Remarks:
270  Generally, GetMappingCylinder will not return the same
271  parameters passed to SetCylinderMapping. However, the
272  location of the cylinder will be the same.
273  If this mapping is not cylindrical, the cylinder will
274  approximate the actual mapping primitive.
275  */
276  bool GetMappingCylinder(
277  ON_Cylinder& cylinder
278  ) const;
279 
280  /*
281  Description:
282  Get a spherical projection parameters from this texture mapping.
283  Parameters:
284  sphere - [out]
285  Returns:
286  True if a valid sphere is returned.
287  Remarks:
288  Generally, GetMappingShere will not return the same
289  parameters passed to SetSphereMapping. However, the
290  location of the sphere will be the same.
291  If this mapping is not cylindrical, the cylinder will
292  approximate the actual mapping primitive.
293  */
294  bool GetMappingSphere(
295  ON_Sphere& sphere
296  ) const;
297 
298  /*
299  Get a box projection from the texture mapping.
300  Parameters:
301  plane - [out]
302  The center of the box is at plane.origin and the sides
303  of the box are parallel to the plane's coordinate planes.
304  dx - [out]
305  The "front" and "back" sides of the box are in spanned
306  by the vectors plane.yaxis and plane.zaxis. The back
307  plane contains the point plane.PointAt(dx[0],0,0) and
308  the front plane contains the point plane.PointAt(dx[1],0,0).
309  dy - [out]
310  The "left" and "right" sides of the box are in spanned
311  by the vectors plane.zaxis and plane.xaxis. The left
312  plane contains the point plane.PointAt(0,dx[0],0) and
313  the back plane contains the point plane.PointAt(0,dy[1],0).
314  dz - [out]
315  The "top" and "bottom" sides of the box are in spanned
316  by the vectors plane.xaxis and plane.yaxis. The bottom
317  plane contains the point plane.PointAt(0,0,dz[0]) and
318  the top plane contains the point plane.PointAt(0,0,dz[1]).
319  Returns:
320  True if a valid box is returned.
321  Remarks:
322  Generally, GetMappingBox will not return the same
323  parameters passed to SetBoxMapping. However, the
324  location of the box will be the same.
325  */
326  bool GetMappingBox(
327  ON_Plane& plane,
328  ON_Interval& dx,
329  ON_Interval& dy,
330  ON_Interval& dz
331  ) const;
332 
333 
334  /*
335  Description:
336  Reverses the texture in the specified direction.
337  Parameters:
338  dir - [in] 0 = reverse "u", 1 = reverse "v", 2 = reverse "w".
339  Remarks:
340  Modies m_uvw so that the spedified direction transforms
341  the texture coordinate t to 1-t.
342  Returns:
343  True if input is valid.
344  */
345  bool ReverseTextureCoordinate( int dir );
346 
347  /*
348  Description:
349  Swaps the specified texture coordinates.
350  Parameters:
351  i - [in]
352  j - [in]
353  Remarks:
354  Modifies m_uvw so that the specified texture coordinates are swapped.
355  Returns:
356  True if input is valid.
357  */
358  bool SwapTextureCoordinate( int i, int j );
359 
360  /*
361  Description:
362  Tiles the specified texture coordinates.
363  Parameters:
364  dir - [in] 0 = "u", 1 = "v", 2 = "w".
365  count - [in] number of tiles
366  offset - [in] offset of the tile
367  Remarks:
368  Modies m_uvw so that the specified texture coordinate is
369  tiled.
370  Returns:
371  True if input is valid.
372  */
373  bool TileTextureCoordinate( int dir, double count, double offset );
374 
375  /*
376  Description:
377  Evaluate the mapping to get a texture coordinate.
378  Parameters:
379  P - [in] Vertex location
380  N - [in] If the mapping projection is ray_projection,
381  then this is the vertex unit normal. Otherwise
382  N is ignored.
383  T - [out] Texture coordinate (u,v,w)
384 
385  P_xform -[in]
386  Transformation to be applied to P before performing
387  the mapping calculation.
388  N_xform - [in]
389  Transformation to be applied to N before performing
390  the mapping calculation. One way to calculate N_xform
391  is to use the call P_xform::GetVectorTransform(N_xform).
392 
393  Returns:
394  Nonzero if evaluation is successful. When the mapping
395  is a box or capped cylinder mapping, the value indicates
396  which side was evaluated.
397 
398  Cylinder mapping:
399  1 = cylinder wall, 2 = bottom cap, 3 = top cap
400  Box mapping:
401  1 = front
402  2 = right
403  3 = back
404  4 = left
405  5 = bottom
406  6 = top
407 
408  See Also:
409  ON_TextureMapping::GetTextureCoordinates
410  ON_Mesh::SetTextureCoordinates
411  */
412  virtual
413  int Evaluate(
414  const ON_3dPoint& P,
415  const ON_3dVector& N,
416  ON_3dPoint* T
417  ) const;
418 
419  virtual
420  int Evaluate(
421  const ON_3dPoint& P,
422  const ON_3dVector& N,
423  ON_3dPoint* T,
424  const ON_Xform& P_xform,
425  const ON_Xform& N_xform
426  ) const;
427 
428  int EvaluatePlaneMapping(
429  const ON_3dPoint& P,
430  const ON_3dVector& N,
431  ON_3dPoint* T
432  ) const;
433 
434  int EvaluateSphereMapping(
435  const ON_3dPoint& P,
436  const ON_3dVector& N,
437  ON_3dPoint* T
438  ) const;
439 
440  int EvaluateCylinderMapping(
441  const ON_3dPoint& P,
442  const ON_3dVector& N,
443  ON_3dPoint* T
444  ) const;
445 
446  int EvaluateBoxMapping(
447  const ON_3dPoint& P,
448  const ON_3dVector& N,
449  ON_3dPoint* T
450  ) const;
451 
452  /*
453  Description:
454  Quickly check to see if a mesh or tag has texture coordinates
455  set by this mapping.
456  Parameters:
457  mesh - [in]
458  tag - [in]
459  object_xform - [in] (optional)
460  If this transform is not NULL, then true will be
461  returned only if the mapping function is the same and
462  the tag's m_mesh_xform field is the same as mesh_xform.
463  This parameter is typically NULL or the value of
464  ON_MappingRef::m_object_xform.
465  Returns:
466  True if the meshes texture coordinates were set by this
467  mapping.
468  */
469  bool HasMatchingTextureCoordinates(
470  const ON_Mesh& mesh,
471  const ON_Xform* object_xform = 0
472  ) const;
473  bool HasMatchingTextureCoordinates(
474  const class ON_MappingTag& tag,
475  const ON_Xform* object_xform = 0
476  ) const;
477 
478  /*
479  Description:
480  Get texture coordinates. This calculation is
481  expensive. When possible, use a MappingMatch()
482  query to avoid unnecessary calculations.
483  Parameters:
484  mesh - [in]
485  T - [out] Texture coordinates returned here.
486  mesh_xform - [in] (optional)
487  If the mesh has been transformed since the texture mapping was set
488  up, pass the transformation here. Typically this is the value
489  of ON_Mesh::m_mapping_xform or ON_MappingRef::m_object_xform
490  bLazy - [in]
491  If true and the mesh.m_T[] values were calculated using
492  this mapping, they are simply copied to the T[] array
493  and no calculations are performed. If you are calling
494  the 3d point version and you care about the z-coordinate,
495  then do not use the lazy option (meshes only store
496  2d texture coordinates).
497  Tside - [out]
498  In the case of divided textures, side information is returned
499  here if a lazy mapping is not done. Otherwise Tside->Count()
500  will be zero.
501  Cylinder mapping:
502  1 = cylinder wall, 2 = bottom cap, 3 = top cap
503  Box mapping:
504  1 = front
505  2 = right
506  3 = back
507  4 = left
508  5 = bottom
509  6 = top
510  Example:
511 
512  ON_TextureMapping mapping = ...;
513  const ON_Mesh* mesh = ...;
514  bool bLazy = true;
515  ON_SimpleArray<ON_3dPoint> T(mesh->VertexCount());
516  T.SetCount(mesh->m_VertexCount());
517  if ( !mapping.GetTextureCoordinates(mesh,3,3,&T[0].x,bLazy) )
518  T.SetCount(0).
519 
520  Returns:
521  True if successful.
522  */
523  bool GetTextureCoordinates(
524  const ON_Mesh& mesh,
526  const ON_Xform* mesh_xform = 0,
527  bool bLazy = false,
528  ON_SimpleArray<int>* Tside = 0
529  ) const;
530 
531  bool GetTextureCoordinates(
532  const ON_Mesh& mesh,
534  const ON_Xform* mesh_xform = 0,
535  bool bLazy = false,
536  ON_SimpleArray<int>* Tside = 0
537  ) const;
538 
539 public:
540  // The only reliable and persistent way to reference texture
541  // mappings is by the mapping_id. If the mapping id is
542  // set to m_srfp_mapping_id, then all other mapping settings
543  // are ignored.
545 
546  // Runtime texture mapping table index.
547  // This value is NOT SAVED IN 3DM FILES.
548  // This value is constant for each runtime instance of Rhino,
549  // but can change each time a model is loaded or saved.
550  // Once a texture mapping is in the CRhinoDoc material table,
551  // its id and index never change in that instance of Rhino.
553 
554  // The texture mapping name is for UI and user comfort.
555  // Duplicates are permitted.
557 
558  //////////////////////////////////////////////////////////
559  //
560  // Mapping types:
561  //
562  // You can either calculate texture coordinates based on
563  // the parameterization of the surface used to create a mesh,
564  // or project the natural parameterization from a mapping
565  // primitive, like a plane, sphere, box, or cylinder.
566  //
567  // Do not change TYPE enum values - they are saved in 3dm files.
568  //
569  enum TYPE
570  {
571  no_mapping = 0,
572 
573  srfp_mapping = 1, // u,v = linear transform of surface params,w = 0
574  plane_mapping = 2, // u,v,w = 3d coordinates wrt frame
575  cylinder_mapping = 3, // u,v,w = logitude, height, radius
576  sphere_mapping = 4, // (u,v,w) = longitude,latitude,radius
577  box_mapping = 5,
578  mesh_mapping_primitive = 6, // m_mapping_primitive is an ON_Mesh
579  srf_mapping_primitive = 7, // m_mapping_primitive is an ON_Surface
580  brep_mapping_primitive = 8, // m_mapping_primitive is an ON_Brep
581 
582  force_32bit_mapping_type = 0xFFFFFFFF
583  };
584 
586 
587  //////////////////////////////////////////////////////////
588  //
589  // Projection:
590  //
591  // When a mapping primitive, like a plane, sphere, box,
592  // or cylinder, is used, there are two projection options.
593  //
594  // clspt_projection: world xyz maps to the point on the
595  // mapping primitive that is closest to xyz.
596  // In this case, ON_TextureMapping::Evaluate
597  // ignores the vector argument.
598  //
599  // ray_projection: world xyz + world vector defines a world line.
600  // The world line is intersected with the mapping
601  // primitive and the intersection point that is
602  // closest to the world xyz point is used to
603  // calculate the mapping parameters.
604  //
605  // The value of m_projection can be changed as needed.
606  //
607  // If m_type = srfp_mapping, then m_projection is ignored.
608  //
610  {
611  no_projection = 0,
612  clspt_projection = 1,
613  ray_projection = 2,
614  force_32bit_mapping_projection = 0xFFFFFFFF
615  };
616 
618 
619  //////////////////////////////////////////////////////////
620  //
621  // Texture space
622  //
623  // When a mapping primitive is a box or a capped cylinder,
624  // there are two options for the mapping. Either the sides
625  // all map to (0,1)x(0,1) (so the either texture map appears
626  // on each side, or the sides map to distinct regions of the
627  // texture space.
628  //
630  {
631  single = 0, // sides and caps map to same texture space
632  divided = 1, // sides and caps map to distinct vertical
633  // regions of texture space.
634  // (0, 1/4, 2/4, 3/4, 1) for uncapped boxes.
635  // (0, 1/6, 2/6, 3/6, 4/6, 5/6, 1) for capped boxes.
636  // (0, 4/6, 5/6, 1) for capped cylinders.
637  force_32bit_texture_space = 0xFFFFFFFF
638  };
639 
641 
642  // The m_bCapped applies to planar, cylinder and box mappings.
643  // If m_bCapped is false, the cylinder or box is "infinite", if m_bCapped is true, they are finite.
644  // In planar mappings, m_bCapped=false means "the Z texture coordinate will always be 0.0"
645  // this is now the default behaviour in Rhino 5.0 - it's what users expect apparently.
646  bool m_bCapped;
647 
648  //////////////////////////////////////////////////////////
649  //
650  // For primitive based mappings, these transformations are
651  // used to map the world coordinate (x,y,z) point P and
652  // surface normal N before it is projected to the normalized
653  // mapping primitive. The surface normal transformation,
654  // m_Nxyz, is always calculated from m_Pxyz. It is a
655  // runtime setting that is not saved in 3dm files.
656  // If m_type is srfp_mapping, then m_Pxyz and m_Nxyz are
657  // ignored.
660 
661  // Transform applied to mapping coordinate (u,v,w) to
662  // convert it into a texture coordinate.
664 
665  // Custom mapping primitive.
667 
668  static TYPE TypeFromInt( int i );
669  static PROJECTION ProjectionFromInt( int i );
670  static TEXTURE_SPACE TextureSpaceFromInt( int i);
671 
672  ON__UINT32 MappingCRC() const;
673 };
674 
675 #if defined(ON_DLL_TEMPLATE)
676 // This stuff is here because of a limitation in the way Microsoft
677 // handles templates and DLLs. See Microsoft's knowledge base
678 // article ID Q168958 for details.
679 #pragma warning( push )
680 #pragma warning( disable : 4231 )
681 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_TextureMapping>;
682 ON_DLL_TEMPLATE template class ON_CLASS ON_ObjectArray<ON_TextureMapping>;
683 #pragma warning( pop )
684 #endif
685 
686 
687 #endif
688 
virtual ON_BOOL32 IsValid(ON_TextLog *text_log=NULL) const =0
virtual ON_BOOL32 Write(ON_BinaryArchive &binary_archive) const
virtual ON_BOOL32 Read(ON_BinaryArchive &binary_archive)
virtual unsigned int SizeOf() const
virtual void Dump(ON_TextLog &) const
ON_Object & operator=(const ON_Object &)
virtual ON_UUID ModelObjectId() const