Free Electron
SurfaceAccessorHoudini.h
Go to the documentation of this file.
1 /* Copyright (C) 2003-2021 Free Electron Organization
2  Any use of this software requires a license. If a valid license
3  was not distributed with this file, visit freeelectron.org. */
4 
5 /** @file */
6 
7 #ifndef __houdini_SurfaceAccessorHoudini_h__
8 #define __houdini_SurfaceAccessorHoudini_h__
9 
10 #define FE_SAH_ASSERT_BOUNDS TRUE
11 #define FE_SAH_MULTIGROUP TRUE
12 
13 namespace fe
14 {
15 namespace ext
16 {
17 
18 //* TODO remove Houdini-only CompoundGroup in favor of general MultiGroup
19 
20 //* TODO rework select() methodology to be reentrant
21 
22 //* TODO remove old style of vertex uvs using e_primitive
23 
24 //* look at VM/VM_Math for simd
25 
26 //* thread-safe only on isolated pages
27 //* different threads can't write to the same page
28 
29 //* GA_AttributeRefMap could replace GEO_AttributeHandleList
30 
31 /**************************************************************************//**
32  @brief Houdini Surface Editing Implementation
33 
34  Note that attempts to access non-existant attributes isn't a failure.
35  New attributes may be added when first written to by a set() method.
36 
37  @ingroup houdini
38 *//***************************************************************************/
39 class FE_DL_EXPORT SurfaceAccessorHoudini:
40  public SurfaceAccessorBase,
41  public CastableAs<SurfaceAccessorHoudini>
42 {
43  public:
45  m_pGdp(NULL),
46  m_pGdpChangeable(NULL),
47  m_pPrimitive(NULL),
48  m_tupleSize(0)
49 //~ ,m_pGroup(NULL)
50  {
51 #ifdef FE_HOUDINI_USE_GA
52 //~ m_pIterator=NULL;
53 #else
54  m_pPoint=NULL;
55  m_pPointChangeable=NULL;
56 #endif
57  setName("SurfaceAccessorHoudini");
58  }
59 
60 virtual ~SurfaceAccessorHoudini(void)
61  {
62 //~#ifdef FE_HOUDINI_USE_GA
63 //~ delete m_pIterator;
64 //~#endif
65 #if FE_HOUDINI_HARDENING
66  if(m_spHardening.isValid())
67  {
68  FEASSERT(m_spSurfaceAccessibleI.isValid());
69  m_spSurfaceAccessibleI->lock(I64(this));
70  m_spHardening=NULL;
71  m_spSurfaceAccessibleI->unlock(I64(this));
72  }
73 #endif
74  }
75 
76  using SurfaceAccessorBase::set;
77  using SurfaceAccessorBase::append;
78  using SurfaceAccessorBase::spatialVector;
79 
80  BWORD bind(SurfaceAccessibleI::Element a_element,
81  SurfaceAccessibleI::Attribute a_attribute)
82  {
83  m_attribute=a_attribute;
84 
85  String name;
86  switch(a_attribute)
87  {
88  case SurfaceAccessibleI::e_generic:
89  case SurfaceAccessibleI::e_position:
90  name="P";
91  break;
92  case SurfaceAccessibleI::e_normal:
93  name="N";
94  break;
95  case SurfaceAccessibleI::e_uv:
96  name="uv";
97  break;
98  case SurfaceAccessibleI::e_color:
99  name="Cd";
100  break;
101  case SurfaceAccessibleI::e_vertices:
102  m_attrName="vertices";
103  FEASSERT(a_element==
104  SurfaceAccessibleI::e_primitive);
105  m_element=a_element;
106  return TRUE;
107  case SurfaceAccessibleI::e_properties:
108  m_attrName="properties";
109  FEASSERT(a_element==
110  SurfaceAccessibleI::e_primitive);
111  m_element=a_element;
112  return TRUE;
113  }
114  return bindInternal(a_element,name);
115  }
116  BWORD bind(SurfaceAccessibleI::Element a_element,
117  const String& a_name)
118  {
119  m_attribute=SurfaceAccessibleI::e_generic;
120 
121  if(a_name=="P")
122  {
123  m_attribute=SurfaceAccessibleI::e_position;
124  }
125  else if(a_name=="N")
126  {
127  m_attribute=SurfaceAccessibleI::e_normal;
128  }
129  else if(a_name=="uv")
130  {
131  m_attribute=SurfaceAccessibleI::e_uv;
132  }
133  else if(a_name=="Cd")
134  {
135  m_attribute=SurfaceAccessibleI::e_color;
136  }
137 
138  return bindInternal(a_element,a_name);
139  }
140 
141  //* as SurfaceAccessorI
142 virtual String type(void) const;
143 
144 virtual U32 count(void) const
145  {
146  FEASSERT(m_pGdp);
147 
148 #if FALSE
149  if(m_attribute!=SurfaceAccessibleI::e_generic &&
150  m_attribute!=
151  SurfaceAccessibleI::e_vertices &&
152  m_attribute!=
153  SurfaceAccessibleI::e_properties &&
154  !isBound())
155  {
156  return 0;
157  }
158 #else
159  if(m_attribute==SurfaceAccessibleI::e_position &&
160  !isBound())
161  {
162  return 0;
163  }
164 #endif
165 
166  switch(m_element)
167  {
168  case SurfaceAccessibleI::e_point:
169 #ifdef FE_HOUDINI_USE_GA
170  return m_pGdp->getNumPoints();
171 #else
172  return m_pGdp->points().entries();
173 #endif
174 
175  case SurfaceAccessibleI::e_vertex:
176  case SurfaceAccessibleI::e_primitive:
177 #ifdef FE_HOUDINI_USE_GA
178  return m_pGdp->getNumPrimitives();
179 #else
180  return m_pGdp->primitives().entries();
181 #endif
182 
183  case SurfaceAccessibleI::e_detail:
184  return 1;
185 
186  case SurfaceAccessibleI::e_pointGroup:
187  case SurfaceAccessibleI::e_primitiveGroup:
188 //~ return m_pGroup? m_pGroup->entries(): 0;
189 #if FE_SAH_MULTIGROUP
190  return m_spMultiGroup->count();
191 #else
192  return m_spCompoundGroup.isValid()?
193  m_spCompoundGroup->count(): 0;
194 #endif
195 
196  default:
197  ;
198  }
199  return 0;
200  }
201 virtual U32 subCount(U32 a_index) const
202  {
203  if(m_attribute!=SurfaceAccessibleI::e_generic &&
204  m_attribute!=
205  SurfaceAccessibleI::e_vertices &&
206  m_attribute!=
207  SurfaceAccessibleI::e_uv &&
208  m_attribute!=
209  SurfaceAccessibleI::e_color &&
210  m_attribute!=
211  SurfaceAccessibleI::e_properties &&
212  !isBound())
213  {
214  return 0;
215  }
216 
217  //* TODO do we really want direct access
218  //* as e_primitiveGroup?
219 
220  const BWORD isPrimitiveUV=
221  ((m_element==SurfaceAccessibleI::e_primitive
222  ||m_element==SurfaceAccessibleI::e_vertex
223  || m_element==
224  SurfaceAccessibleI::e_primitiveGroup) &&
225  m_attribute==SurfaceAccessibleI::e_uv);
226 
227  if(m_element==
228  SurfaceAccessibleI::e_primitiveGroup ||
229  m_element==
230  SurfaceAccessibleI::e_vertex ||
231  m_attribute==SurfaceAccessibleI::e_vertices
232  || isPrimitiveUV)
233  {
234  FEASSERT(m_element==
235  SurfaceAccessibleI::e_primitiveGroup
236  || m_element==
237  SurfaceAccessibleI::e_vertex
238  || m_element==
239  SurfaceAccessibleI::e_primitive);
240 
241  const_cast<SurfaceAccessorHoudini*>(this)
242  ->select(a_index,0);
243 
244  if(m_element==
245  SurfaceAccessibleI::e_primitiveGroup &&
246  !m_pPrimitive)
247  {
248  return 1;
249  }
250 
251  FEASSERT(m_pPrimitive);
252  return m_pPrimitive->getVertexCount();
253  }
254 
255  return 1;
256 
257  // TODO check what really needs sub-indexes
258 // return m_handle.entries();
259  }
260 
261 
262 virtual void set(U32 a_index,U32 a_subIndex,String a_string)
263  {
264 #if FE_SAH_ASSERT_BOUNDS
265  FEASSERT(a_index<count());
266  FEASSERT(a_subIndex<subCount(a_index));
267 #endif
268  if(m_attribute!=SurfaceAccessibleI::e_vertices &&
269  m_attribute!=
270  SurfaceAccessibleI::e_properties &&
271  !isBound())
272  {
273  addString();
274  }
275  select(a_index,a_subIndex);
276 
277  UT_String utString(a_string.c_str());
278  m_handle.setString(utString);
279  }
280 virtual String string(U32 a_index,U32 a_subIndex=0)
281  {
282 #if FE_SAH_ASSERT_BOUNDS
283  FEASSERT(a_index<count());
284  FEASSERT(a_subIndex<subCount(a_index));
285 #endif
286  select(a_index,a_subIndex);
287 
288  if(m_attribute==SurfaceAccessibleI::e_vertices ||
289  m_attribute==
290  SurfaceAccessibleI::e_properties)
291  {
292  return String();
293  }
294 
295  UT_String utString;
296  m_handle.getString(utString,a_subIndex);
297  return String(utString.buffer());
298  }
299 
300 virtual void set(U32 a_index,U32 a_subIndex,I32 a_integer)
301  {
302 #if FE_SAH_ASSERT_BOUNDS
303  FEASSERT(a_index<count());
304  FEASSERT(a_subIndex<subCount(a_index));
305 #endif
306 
307 #ifdef FE_HOUDINI_USE_GA
308  if(m_element==SurfaceAccessibleI::e_point &&
309  m_handleIntRW.isValid())
310  {
311 #if FE_HOUDINI_12_5_PLUS
312  m_handleIntRW.set(m_pGdp->pointOffset(a_index),
313  a_subIndex,a_integer);
314  return;
315  return;
316 #else
317  if(!a_subIndex)
318  {
319  m_handleIntRW.set(
320  m_pGdp->pointOffset(a_index),
321  a_integer);
322  return;
323  }
324 #endif
325  }
326 #endif
327 
328  if(m_attribute!=SurfaceAccessibleI::e_vertices &&
329  m_attribute!=
330  SurfaceAccessibleI::e_properties &&
331  !isBound())
332  {
333  addInteger();
334  }
335 
336  select(a_index,a_subIndex);
337 
338  if(m_element==
339  SurfaceAccessibleI::e_primitiveGroup ||
340  m_attribute==SurfaceAccessibleI::e_vertices)
341  {
342  FEASSERT(m_element==
343  SurfaceAccessibleI::e_primitiveGroup
344  || m_element==
345  SurfaceAccessibleI::e_primitive);
346  FEASSERT(m_pPrimitive);
347 #ifdef FE_HOUDINI_USE_GA
348  const GA_Offset offset=
349  m_pGdp->pointOffset(a_integer);
350  const_cast<GEO_Primitive*>(m_pPrimitive)
351  ->setPointOffset(a_subIndex,offset);
352 #else
353  const GB_Element* pElement=
354  m_pGdp->points()(a_integer);
355  const_cast<GEO_Primitive*>(m_pPrimitive)
356  ->getVertex(a_subIndex).setPt(
357  const_cast<GB_Element*>(pElement));
358 #endif
359  }
360 
361  if(m_attribute==SurfaceAccessibleI::e_properties)
362  {
363  FEASSERT(m_element==
364  SurfaceAccessibleI::e_primitiveGroup
365  || m_element==
366  SurfaceAccessibleI::e_primitive);
367  FEASSERT(m_pPrimitive);
368  if(a_subIndex==SurfaceAccessibleI::e_openCurve)
369  {
370  GEO_Face* pGeoFace=
371  dynamic_cast<GEO_Face*>(
372  const_cast<GEO_Primitive*>(
373  m_pPrimitive));
374  if(!pGeoFace)
375  {
376  return;
377  }
378 
379  if(pGeoFace->isClosed())
380  {
381  if(a_integer)
382  {
383  pGeoFace->open();
384  }
385  }
386  else if(!a_integer)
387  {
388  pGeoFace->close();
389  }
390 
391  return;
392  }
393  if(a_subIndex==SurfaceAccessibleI::e_countU ||
394  a_subIndex==
395  SurfaceAccessibleI::e_countV ||
396  a_subIndex==
397  SurfaceAccessibleI::e_wrappedU ||
398  a_subIndex==
399  SurfaceAccessibleI::e_wrappedV)
400  {
401 #ifdef FE_HOUDINI_USE_GA
402  if(m_pPrimitive->getTypeId().get()!=
403  GEO_PRIMMESH)
404  {
405  return;
406  }
407 #else
408  if(m_pPrimitive->getPrimitiveId()!=
409  GEOPRIMMESH)
410  {
411  return;
412  }
413 #endif
414  const GEO_PrimMesh* pPrimMesh=
415  dynamic_cast<const GEO_PrimMesh*>(
416  m_pPrimitive);
417  if(pPrimMesh)
418  {
419  switch(a_subIndex)
420  {
421  case SurfaceAccessibleI::e_countU:
422 // return pPrimMesh->getNumCols();
423  case SurfaceAccessibleI::e_countV:
424 // return pPrimMesh->getNumRows();
425  case SurfaceAccessibleI::e_wrappedU:
426 // return pPrimMesh->isWrappedU();
427  case SurfaceAccessibleI::e_wrappedV:
428 // return pPrimMesh->isWrappedV();
429  default:
430  ;
431  }
432  }
433  }
434  return;
435  }
436 
437  m_handle.setI(a_integer);
438  }
439 virtual I32 integer(U32 a_index,U32 a_subIndex=0)
440  {
441 #if FE_SAH_ASSERT_BOUNDS
442  FEASSERT(a_index<count());
443  FEASSERT(m_attribute==
444  SurfaceAccessibleI::e_properties ||
445  a_subIndex<subCount(a_index));
446 #endif
447 
448 #ifdef FE_HOUDINI_USE_GA
449  if(m_element==SurfaceAccessibleI::e_point &&
450  m_handleIntRO.isValid())
451  {
452 #if FE_HOUDINI_12_5_PLUS
453  return m_handleIntRO.get(
454  m_pGdp->pointOffset(a_index),
455  a_subIndex);
456 #else
457  if(!a_subIndex)
458  {
459  return m_handleIntRO.get(
460  m_pGdp->pointOffset(a_index));
461  }
462 #endif
463  }
464 #endif
465 
466  select(a_index,a_subIndex);
467 
468  if(m_element==SurfaceAccessibleI::e_pointGroup ||
469  m_element==
470  SurfaceAccessibleI::e_primitiveGroup)
471  {
472 #if FE_SAH_MULTIGROUP
473  if(m_spMultiGroup.isNull())
474  {
475  return -1;
476  }
477  return m_spMultiGroup->at(a_index);
478 #else
479  if(m_spCompoundGroup.isNull())
480  {
481  return -1;
482  }
483  return m_spCompoundGroup->getIndex();
484 #endif
485  }
486 
487 //~ if(m_element==SurfaceAccessibleI::e_pointGroup)
488 //~ {
489 //~#ifdef FE_HOUDINI_USE_GA
490 //~ if(!m_pIterator || !m_pIterator->isValid())
491 //~ {
492 //~ return -1;
493 //~ }
494 //~ return m_pGdp->pointIndex(
495 //~ m_pIterator->getOffset());
496 //~#else
497 //~ FEASSERT(m_pPoint);
498 //~ return m_pPoint->getNum();
499 //~#endif
500 //~ }
501 //~
502 //~ if(m_element==
503 //~ SurfaceAccessibleI::e_primitiveGroup)
504 //~ {
505 //~ FEASSERT(m_pPrimitive);
506 //~#ifdef FE_HOUDINI_USE_GA
507 //~ const GA_Offset offset=
508 //~ m_pIterator->getOffset();
509 //~ return m_pGdp->primitiveIndex(offset);
510 //~#else
511 //~ return m_pPrimitive->getNum();
512 //~#endif
513 //~ }
514 
515  if(m_attribute==SurfaceAccessibleI::e_vertices)
516  {
517  FEASSERT(m_element==
518  SurfaceAccessibleI::e_primitive);
519  FEASSERT(m_pPrimitive);
520 #ifdef FE_HOUDINI_USE_GA
521  const GA_Offset offset=m_pPrimitive
522  ->getPointOffset(a_subIndex);
523  return m_pGdp->pointIndex(offset);
524 #else
525  return m_pPrimitive->getVertex(a_subIndex)
526  .getBasePt()->getNum();
527 #endif
528  return 1;
529  }
530 
531  if(m_attribute==SurfaceAccessibleI::e_properties)
532  {
533  FEASSERT(m_element==
534  SurfaceAccessibleI::e_primitiveGroup
535  || m_element==
536  SurfaceAccessibleI::e_primitive);
537  FEASSERT(m_pPrimitive);
538  if(a_subIndex==SurfaceAccessibleI::e_openCurve)
539  {
540  const GEO_Face* pGeoFace=
541  dynamic_cast<const GEO_Face*>(
542  m_pPrimitive);
543 
544  return pGeoFace && !pGeoFace->isClosed();
545  }
546  if(a_subIndex==SurfaceAccessibleI::e_countU ||
547  a_subIndex==
548  SurfaceAccessibleI::e_countV ||
549  a_subIndex==
550  SurfaceAccessibleI::e_wrappedU ||
551  a_subIndex==
552  SurfaceAccessibleI::e_wrappedV)
553  {
554 #ifdef FE_HOUDINI_USE_GA
555  if(m_pPrimitive->getTypeId().get()!=
556  GEO_PRIMMESH)
557  {
558  return 0;
559  }
560 #else
561  if(m_pPrimitive->getPrimitiveId()!=
562  GEOPRIMMESH)
563  {
564  return 0;
565  }
566 #endif
567  const GEO_PrimMesh* pPrimMesh=
568  dynamic_cast<const GEO_PrimMesh*>(
569  m_pPrimitive);
570  if(pPrimMesh)
571  {
572  switch(a_subIndex)
573  {
574  case SurfaceAccessibleI::e_countU:
575  return pPrimMesh->getNumCols();
576  case SurfaceAccessibleI::e_countV:
577  return pPrimMesh->getNumRows();
578  case SurfaceAccessibleI::e_wrappedU:
579  return pPrimMesh->isWrappedU();
580  case SurfaceAccessibleI::e_wrappedV:
581  return pPrimMesh->isWrappedV();
582  default:
583  ;
584  }
585  }
586  }
587  return 0;
588  }
589 
590  return m_handle.getI(a_subIndex);
591 
592  }
593 virtual I32 duplicate(U32 a_index,U32 a_subIndex=0)
594  {
595  //* TODO maybe other elements
596  if(m_element!=SurfaceAccessibleI::e_point &&
597  m_element!=SurfaceAccessibleI::e_primitive)
598  {
599  return -1;
600  }
601 
602  FEASSERT(m_pGdpChangeable);
603  if(!m_pGdpChangeable)
604  {
605  return -1;
606  }
607 
608  I32 dupIndex= -1;
609  GEO_Primitive* pDupPrimitive=NULL;
610 
611 #ifdef FE_HOUDINI_USE_GA
612  if(m_element==SurfaceAccessibleI::e_point)
613  {
614  const GA_Offset offset=
615  m_pGdpChangeable->pointOffset(a_index);
616  GA_Offset dupOffset=
617  m_pGdpChangeable->appendPointCopy(
618  offset);
619  return m_pGdpChangeable->pointIndex(dupOffset);
620  }
621  else
622  {
623  select(a_index,a_subIndex);
624 
625  FEASSERT(m_pPrimitive);
626  const GA_PrimitiveTypeId primType=
627  m_pPrimitive->getTypeId();
628 #if FE_HOUDINI_14_PLUS
629  //* TODO verify this does the same thing
630  pDupPrimitive=
631  m_pGdpChangeable->appendPrimitive(
632  primType);
633  m_pGdpChangeable->copyPrimitiveAttributes(
634  *pDupPrimitive,*m_pPrimitive);
635 #else
636  pDupPrimitive=
637  m_pGdpChangeable->appendPrimitive(
638  primType,m_pPrimitive,NULL);
639 #endif
640  dupIndex=pDupPrimitive->getNum();
641  }
642 #else
643  if(m_element==SurfaceAccessibleI::e_point)
644  {
645  select(a_index,a_subIndex);
646 
647  FEASSERT(m_pPoint);
648  const GEO_Point* pDupPoint=
649  m_pGdpChangeable->appendPoint(
650  *m_pPoint);
651  return pDupPoint->getNum();
652  }
653  else
654  {
655  select(a_index,a_subIndex);
656 
657  FEASSERT(m_pPrimitive);
658  const unsigned primType=
659  m_pPrimitive->getPrimitiveId();
660  pDupPrimitive=
661  m_pGdpChangeable->appendPrimitive(
662  primType,m_pPrimitive);
663  dupIndex=pDupPrimitive->getNum();
664  }
665 #endif
666 
667  const GU_PrimPoly* pPolyOrig=
668  dynamic_cast<const GU_PrimPoly*>(
669  m_pPrimitive);
670  GU_PrimPoly* pPolyDup=
671  dynamic_cast<GU_PrimPoly*>(pDupPrimitive);
672 
673  const U32 vertCount=subCount(a_index);
674  for(U32 vertIndex=0;vertIndex<vertCount;
675  vertIndex++)
676  {
677  const I32 pointIndex=integer(a_index,vertIndex);
678  append(dupIndex,pointIndex);
679  }
680 
681  FEASSERT(subCount(dupIndex)==vertCount);
682 
683  if(pPolyOrig && pPolyDup && pPolyOrig->isClosed())
684  {
685  pPolyDup->close();
686  }
687 
688  return dupIndex;
689  }
690 virtual I32 append(SurfaceAccessibleI::Form a_form)
691  {
692  if(m_element==SurfaceAccessibleI::e_point)
693  {
694 // GEO_Point* pGeoPoint=
695  m_pGdpChangeable->appendPoint();
696 
697  return count()-1;
698  }
699 
700  if(m_element==SurfaceAccessibleI::e_primitive)
701  {
702  //* add new poly
703 
704  const int open=
705  (a_form==SurfaceAccessibleI::e_open)?
706  GU_POLY_OPEN: GU_POLY_CLOSED;
707 
708  int npts=0;
709  int appendPts=0;
710 // GU_PrimPoly* pGuPrimPoly=
711  GU_PrimPoly::build(m_pGdpChangeable,
712  npts,open,appendPts);
713 
714  return count()-1;
715  }
716 
717  return -1;
718  }
719 virtual void append(U32 a_index,I32 a_integer)
720  {
721  if(m_element==SurfaceAccessibleI::e_detail)
722  {
723  m_tupleSize+=a_integer;
724  return;
725  }
726 
727  if(m_element!=SurfaceAccessibleI::e_pointGroup &&
728  m_element!=
729  SurfaceAccessibleI::e_primitiveGroup &&
730  !(m_element==
731  SurfaceAccessibleI::e_primitive &&
732  m_attribute==
733  SurfaceAccessibleI::e_vertices))
734  {
735  return;
736  }
737 
738  FEASSERT(m_pGdpChangeable);
739  if(!m_pGdpChangeable)
740  {
741  return;
742  }
743 
744  if(m_element==SurfaceAccessibleI::e_primitive)
745  {
746  select(a_index,0);
747 
748  GEO_TriMesh* pGeoTriMesh=
749  dynamic_cast<GEO_TriMesh*>(
750  const_cast<GEO_Primitive*>(
751  m_pPrimitive));
752  FEASSERT(pGeoTriMesh);
753 #ifdef FE_HOUDINI_USE_GA
754  const GA_Offset offset=
755  m_pGdpChangeable->pointOffset(
756  a_integer);
757 // const int vertIndex=
758  pGeoTriMesh->appendVertex(offset);
759 #else
760  GEO_Point* pPoint=
761  m_pGdpChangeable->points()(a_integer);
762 // const int vertIndex=
763  pGeoTriMesh->appendVertex(pPoint);
764 #endif
765  return;
766  }
767 
768  // a_index ignored
769 
770 //~ if(!m_pGroup)
771 //~ {
772 //~ if(m_element==SurfaceAccessibleI::e_pointGroup)
773 //~ {
774 //~ m_pGroup=m_pGdpChangeable->newPointGroup(
775 //~ m_attrName.c_str());
776 //~ }
777 //~ else
778 //~ {
779 //~ m_pGroup=
780 //~ m_pGdpChangeable->newPrimitiveGroup(
781 //~ m_attrName.c_str());
782 //~ }
783 //~ }
784 //~
785 //~ FEASSERT(m_pGroup);
786 //~
787 //~#ifdef FE_HOUDINI_USE_GA
788 //~ m_pGroup->addIndex(a_integer);
789 //~#else
790 //~ m_pGroup->add(a_integer);
791 //~#endif
792 
793 #if FE_SAH_MULTIGROUP
794  if(m_spMultiGroup.isValid())
795  {
796  m_spMultiGroup->add(a_integer);
797  }
798 #else
799  if(m_spCompoundGroup.isValid())
800  {
801  m_spCompoundGroup->append(a_integer);
802  }
803 #endif
804  }
805 virtual void append(Array< Array<I32> >& a_rPrimVerts);
806 
807 virtual void remove(U32 a_index,I32 a_integer)
808  {
809  FEASSERT(m_pGdpChangeable);
810  if(!m_pGdpChangeable)
811  {
812  return;
813  }
814 
815 #ifdef FE_HOUDINI_USE_GA
816  if(m_element==SurfaceAccessibleI::e_point)
817  {
818  m_pGdpChangeable->destroyPointIndex(a_index);
819  return;
820  }
821 
822  if(m_element==SurfaceAccessibleI::e_primitive)
823  {
824  m_pGdpChangeable->destroyPrimitiveIndex(
825  a_index);
826  return;
827  }
828 #else
829  //* TODO
830 #endif
831 
832  if(m_element!=SurfaceAccessibleI::e_pointGroup &&
833  m_element!=
834  SurfaceAccessibleI::e_primitiveGroup)
835  {
836  return;
837  }
838 
839 //~ if(!m_pGroup)
840 //~ {
841 //~ return;
842 //~ }
843 //~
844 //~ FEASSERT(m_pGroup);
845 //~#ifdef FE_HOUDINI_USE_GA
846 //~ m_pGroup->removeIndex(a_index);
847 //~#else
848 //~ m_pGroup->remove(a_index);
849 //~#endif
850 
851 #if FE_SAH_MULTIGROUP
852  if(m_spMultiGroup.isValid())
853  {
854  m_spMultiGroup->remove(a_integer);
855  }
856 #else
857  if(m_spCompoundGroup.isValid())
858  {
859  m_spCompoundGroup->remove(a_index);
860  }
861 #endif
862  }
863 
864 virtual void set(U32 a_index,U32 a_subIndex,Real a_real)
865  {
866 #ifdef FE_HOUDINI_USE_GA
867  if(m_element==SurfaceAccessibleI::e_point &&
868  m_handleRealRW.isValid())
869  {
870 #if FE_SAH_ASSERT_BOUNDS
871  FEASSERT(a_index<count());
872  FEASSERT(a_subIndex<subCount(a_index));
873 #endif
874 
875 #if FE_HOUDINI_12_5_PLUS
876  m_handleRealRW.set(m_pGdp->pointOffset(a_index),
877  a_subIndex,a_real);
878  return;
879  return;
880 #else
881  if(!a_subIndex)
882  {
883  m_handleRealRW.set(
884  m_pGdp->pointOffset(a_index),
885  a_real);
886  return;
887  }
888 #endif
889  }
890 #endif
891 
892  if(m_attribute!=SurfaceAccessibleI::e_vertices &&
893  m_attribute!=
894  SurfaceAccessibleI::e_properties &&
895  !isBound())
896  {
897  addReal();
898  }
899 #if FE_SAH_ASSERT_BOUNDS
900  FEASSERT(a_index<count());
901 #endif
902  select(a_index,a_subIndex);
903 
904 #if FE_SAH_ASSERT_BOUNDS
905 // FEASSERT(a_subIndex<subCount(a_index));
906 #endif
907 
908  m_handle.setF(a_real,a_subIndex);
909  }
910 virtual Real real(U32 a_index,U32 a_subIndex=0)
911  {
912 #if FE_SAH_ASSERT_BOUNDS
913  FEASSERT(a_index<count());
914  FEASSERT(a_subIndex<subCount(a_index));
915 #endif
916 
917 #ifdef FE_HOUDINI_USE_GA
918  if(m_element==SurfaceAccessibleI::e_point &&
919  m_handleRealRO.isValid())
920  {
921 #if FE_HOUDINI_12_5_PLUS
922  return m_handleRealRO.get(
923  m_pGdp->pointOffset(a_index),
924  a_subIndex);
925 #else
926  if(!a_subIndex)
927  {
928  return m_handleRealRO.get(
929  m_pGdp->pointOffset(a_index));
930  }
931 #endif
932  }
933 #endif
934 
935  select(a_index,a_subIndex);
936 
937  if(m_attribute==SurfaceAccessibleI::e_vertices ||
938  m_attribute==
939  SurfaceAccessibleI::e_properties)
940  {
941  return 0.0;
942  }
943 
944  return m_handle.getF(a_subIndex);
945  }
946 
947 virtual void set(U32 a_index,U32 a_subIndex,
948  const SpatialVector& a_vector)
949  {
950  if(m_attribute==SurfaceAccessibleI::e_properties)
951  {
952  return;
953  }
954 
955  UT_Vector3 utVector3(a_vector[0],
956  a_vector[1],a_vector[2]);
957 
958 #ifdef FE_HOUDINI_USE_GA
959  if(m_element==SurfaceAccessibleI::e_point &&
960  m_handleV3RW.isValid())
961  {
962 #if FE_HOUDINI_12_5_PLUS
963  m_handleV3RW.set(m_pGdp->pointOffset(a_index),
964  a_subIndex,utVector3);
965  return;
966  return;
967 #else
968  if(!a_subIndex)
969  {
970  m_handleV3RW.set(
971  m_pGdp->pointOffset(a_index),
972  utVector3);
973  return;
974  }
975 #endif
976  }
977 #endif
978 
979  const BWORD isPrimitiveUV=
980  ((m_element==SurfaceAccessibleI::e_primitive
981  || m_element==SurfaceAccessibleI::e_vertex
982  || m_element==
983  SurfaceAccessibleI::e_primitiveGroup) &&
984  m_attribute==SurfaceAccessibleI::e_uv);
985 
986  if(m_element!=SurfaceAccessibleI::e_pointGroup &&
987  m_element!=
988  SurfaceAccessibleI::e_primitiveGroup &&
989  m_attribute!=
990  SurfaceAccessibleI::e_vertices &&
991  !isBound())
992  {
993  addSpatialVector();
994  }
995 
996 #if FE_SAH_ASSERT_BOUNDS
997  FEASSERT(a_index<count());
998  FEASSERT(a_subIndex<subCount(a_index));
999 #endif
1000 
1001  select(a_index,a_subIndex);
1002 
1003  if(m_element==SurfaceAccessibleI::e_pointGroup)
1004  {
1005 #ifdef FE_HOUDINI_USE_GA
1006 //~ if(!m_pIterator || !m_pIterator->isValid())
1007 //~ {
1008 //~ return;
1009 //~ }
1010 //~ m_pGdpChangeable->setPos3(
1011 //~ m_pIterator->getOffset(),utVector3);
1012 #if FE_SAH_MULTIGROUP
1013  if(m_spMultiGroup.isNull())
1014  {
1015  return;
1016  }
1017  const I32 elementIndex=
1018  m_spMultiGroup->at(a_index);
1019 #else
1020  if(m_spCompoundGroup.isNull())
1021  {
1022  return;
1023  }
1024  const I32 elementIndex=
1025  m_spCompoundGroup->getIndex();
1026 #endif
1027  const GA_Offset offset=
1028  m_pGdpChangeable->pointOffset(
1029  elementIndex);
1030  m_pGdpChangeable->setPos3(offset,utVector3);
1031 #else
1032  m_pPointChangeable->setPos(utVector3);
1033 #endif
1034  return;
1035  }
1036 
1037  if(m_element==
1038  SurfaceAccessibleI::e_primitiveGroup ||
1039  m_attribute==SurfaceAccessibleI::e_vertices)
1040  {
1041  FEASSERT(m_element==
1042  SurfaceAccessibleI::e_primitiveGroup
1043  || m_element==
1044  SurfaceAccessibleI::e_primitive);
1045  FEASSERT(m_pPrimitive);
1046 #ifdef FE_HOUDINI_USE_GA
1047  const GA_Offset offset=
1048  m_pPrimitive->getPointOffset(a_subIndex);
1049  m_pGdpChangeable->setPos3(offset,utVector3);
1050 #else
1051  m_pPrimitive->getVertex(a_subIndex).getPt()
1052  ->setPos(utVector3);
1053 #endif
1054  return;
1055  }
1056 
1057  m_handle.setV3(utVector3);
1058  }
1059 virtual SpatialVector spatialVector(U32 a_index,U32 a_subIndex=0)
1060  {
1061 #if FE_SAH_ASSERT_BOUNDS
1062  FEASSERT(a_index<count());
1063  FEASSERT(a_subIndex<subCount(a_index));
1064 #endif
1065  if(m_attribute==SurfaceAccessibleI::e_properties)
1066  {
1067  return SpatialVector(0.0,0.0,0.0);
1068  }
1069 
1070 #ifdef FE_HOUDINI_USE_GA
1071  if(m_element==SurfaceAccessibleI::e_point &&
1072  m_handleV3RO.isValid())
1073  {
1074 #if FE_HOUDINI_12_5_PLUS
1075  return Vector3f(m_handleV3RO.get(
1076  m_pGdp->pointOffset(a_index),
1077  a_subIndex).data());
1078 #else
1079  if(!a_subIndex)
1080  {
1081  return Vector3f(m_handleV3RO.get(
1082  m_pGdp->pointOffset(a_index))
1083  .data());
1084  }
1085 #endif
1086  }
1087 #endif
1088 
1089  select(a_index,a_subIndex);
1090 
1091  if(m_element==SurfaceAccessibleI::e_pointGroup)
1092  {
1093 #ifdef FE_HOUDINI_USE_GA
1094 //~ if(!m_pIterator || !m_pIterator->isValid())
1095 //~ {
1096 //~ return SpatialVector(0.0,0.0,0.0);
1097 //~ }
1098 //~ const UT_Vector3 utVector3=m_pGdp->getPos3(
1099 //~ m_pIterator->getOffset());
1100 //~ return SpatialVector(utVector3.data());
1101 #if FE_SAH_MULTIGROUP
1102  if(m_spMultiGroup.isNull())
1103  {
1104  return SpatialVector(0.0,0.0,0.0);
1105  }
1106  const I32 elementIndex=
1107  m_spMultiGroup->at(a_index);
1108 #else
1109  if(m_spCompoundGroup.isNull())
1110  {
1111  return SpatialVector(0.0,0.0,0.0);
1112  }
1113  const I32 elementIndex=
1114  m_spCompoundGroup->getIndex();
1115 #endif
1116  const GA_Offset offset=
1117  m_pGdp->pointOffset(elementIndex);
1118  const UT_Vector3 utVector3=
1119  m_pGdp->getPos3(offset);
1120  return Vector3f(utVector3.data());
1121 #else
1122  FEASSERT(m_pPoint);
1123  UT_Vector3 utVector3=m_pPoint->getPos();
1124  return Vector3f(utVector3.data());
1125 #endif
1126  }
1127 
1128  if(m_element==
1129  SurfaceAccessibleI::e_primitiveGroup ||
1130  m_attribute==SurfaceAccessibleI::e_vertices)
1131  {
1132  FEASSERT(m_element==
1133  SurfaceAccessibleI::e_primitiveGroup
1134  || m_element==
1135  SurfaceAccessibleI::e_primitive);
1136  FEASSERT(m_pPrimitive);
1137 #ifdef FE_HOUDINI_USE_GA
1138  const GA_Offset offset=
1139  m_pPrimitive->getPointOffset(
1140  a_subIndex);
1141  const UT_Vector3 utVector3=
1142  m_pGdp->getPos3(offset);
1143  return Vector3f(utVector3.data());
1144 #else
1145  UT_Vector3 utVector3=m_pPrimitive
1146  ->getVertex(a_subIndex).getPos();
1147  Vector3f vector(utVector3.data());
1148  return vector;
1149 #endif
1150  }
1151 
1152  UT_Vector3 utVector3=m_handle.getV3();
1153  Vector3f vector(utVector3.data());
1154  return vector;
1155  }
1156 virtual BWORD spatialVector(SpatialVector* a_pVectorArray,
1157  const Vector2i* a_pIndexArray,I32 a_arrayCount)
1158  {
1159 #ifdef FE_HOUDINI_USE_GA
1160  if(m_element==SurfaceAccessibleI::e_point &&
1161  m_handleV3RO.isValid())
1162  {
1163  for(I32 arrayIndex=0;arrayIndex<a_arrayCount;
1164  arrayIndex++)
1165  {
1166  a_pVectorArray[arrayIndex]=
1167  Vector3f(m_handleV3RO.get(
1168  m_pGdp->pointOffset(
1169  a_pIndexArray[arrayIndex][0]))
1170  .data());
1171  }
1172 
1173  return TRUE;
1174  }
1175 #endif
1176 
1177  return SurfaceAccessorBase::spatialVector(
1178  a_pVectorArray,a_pIndexArray,a_arrayCount);
1179  }
1180 
1181  sp<SurfaceAccessibleI> surfaceAccessible(void)
1182  { return m_spSurfaceAccessibleI; }
1183 
1184  //* Houdini specific
1185  void setGdp(const GU_Detail* a_pGdp)
1186  {
1187  m_pGdp=a_pGdp;
1188  m_pGdpChangeable=NULL;
1189  }
1190  void setGdpChangeable(GU_Detail* a_pGdp)
1191  {
1192  m_pGdp=a_pGdp;
1193  m_pGdpChangeable=a_pGdp;
1194  }
1195 const GU_Detail* gdp(void) { return m_pGdp; }
1196  GU_Detail* gdpChangeable(void) { return m_pGdpChangeable; }
1197 
1198  void harden(void);
1199 
1200  private:
1201 virtual BWORD bindInternal(SurfaceAccessibleI::Element a_element,
1202  const String& a_name);
1203 
1204  void addString(void);
1205  void addInteger(void);
1206  void addReal(void);
1207  void addSpatialVector(void);
1208 
1209  BWORD isBound(void) const
1210  { return (m_handle.isAttributeValid() ||
1211 #if FE_SAH_MULTIGROUP
1212  m_spMultiGroup.isValid()
1213 #else
1214  m_spCompoundGroup.isValid()
1215 #endif
1216  );
1217  }
1218 
1219  void select(U32 a_index,U32 a_subIndex);
1220 
1221 const GU_Detail* m_pGdp;
1222  GU_Detail* m_pGdpChangeable;
1223 
1224  GEO_AttributeHandle m_handle;
1225 const GEO_Primitive* m_pPrimitive;
1226 
1227 //~ U32 m_groupIndex;
1228 
1229  I32 m_tupleSize;
1230 
1231 #ifdef FE_HOUDINI_USE_GA
1232 //~ GA_ElementGroup* m_pGroup;
1233 
1234 //~ GA_Iterator* m_pIterator;
1235 
1236  GA_ROHandleI m_handleIntRO;
1237  GA_RWHandleI m_handleIntRW;
1238  GA_ROHandleF m_handleRealRO;
1239  GA_RWHandleF m_handleRealRW;
1240  GA_ROHandleV3 m_handleV3RO;
1241  GA_RWHandleV3 m_handleV3RW;
1242 #else
1243 const GEO_Point* m_pPoint;
1244  GEO_Point* m_pPointChangeable;
1245 //~ GB_Group* m_pGroup;
1246 #endif
1247 
1248  class CompoundGroup: public Counted
1249  {
1250  public:
1251  CompoundGroup(void):
1252  m_groupIndex(-1)
1253  {
1254 #ifdef FE_HOUDINI_USE_GA
1255  m_pIterator=NULL;
1256 #else
1257 #endif
1258  }
1259 
1260  virtual ~CompoundGroup(void) {}
1261 
1262  void bind(sp<SurfaceAccessorHoudini>
1263  a_spSurfaceAccessorHoudini)
1264  { m_spSurfaceAccessorHoudini=
1265  a_spSurfaceAccessorHoudini; }
1266 
1267  void scan(String a_patterns);
1268  void create(String a_groupName);
1269 
1270  void append(I32 a_index);
1271  void remove(I32 a_index);
1272 
1273  I32 count(void);
1274  void select(I32 a_index);
1275 
1276  I32 getIndex(void);
1277  const GEO_Point* getPoint(void);
1278  const GEO_Primitive* getPrimitive(void);
1279 
1280  sp<SurfaceAccessorHoudini> m_spSurfaceAccessorHoudini;
1281 
1282  Array<Vector2i> m_startEnd;
1283  I32 m_groupIndex;
1284  U32 m_subIndex;
1285 
1286  const GEO_Primitive* m_pPrimitive;
1287 
1288 #ifdef FE_HOUDINI_USE_GA
1289  //* NOTE pointers may have been cast from const
1290  //* TODO changeable distinction
1291 
1292  Array<GA_ElementGroup*> m_groupArray;
1293  GA_Iterator* m_pIterator;
1294 
1295 #else
1296  Array<GB_Group*> m_groupArray;
1297  const GEO_Point* m_pPoint;
1298  GEO_Point* m_pPointChangeable;
1299 #endif
1300  };
1301 
1302 #if FE_SAH_MULTIGROUP
1304 #else
1305  sp<CompoundGroup> m_spCompoundGroup;
1306 #endif
1307 
1308 #if FE_HOUDINI_HARDENING
1309  public:
1310 
1311  class Hardening: public Handled<Hardening>
1312  {
1313  public:
1314  Hardening(void):
1315  m_pHarden(NULL) {}
1316  virtual ~Hardening(void)
1317  { delete m_pHarden; }
1318 
1319  void harden(GA_AutoHardenForThreading* a_pHarden)
1320  { m_pHarden=a_pHarden; }
1321  BWORD hardened(void) const
1322  { return m_pHarden!=NULL; }
1323 
1324  private:
1325  GA_AutoHardenForThreading* m_pHarden;
1326  };
1327  sp<Hardening> m_spHardening;
1328 #endif
1329 };
1330 
1331 } /* namespace ext */
1332 } /* namespace fe */
1333 
1334 #endif /* __houdini_SurfaceAccessorHoudini_h__ */
Heap-based support for classes participating in fe::ptr <>
Definition: Counted.h:35
kernel
Definition: namespace.dox:3
Houdini Surface Editing Implementation.
Definition: SurfaceAccessorHoudini.h:39
Common Functionality for Accessor Surface.
Definition: SurfaceAccessorBase.h:20
Automatically reference-counted string container.
Definition: String.h:128
Wrapper for std::vector.
Definition: Array.h:21
Intrusive Smart Pointer.
Definition: src/core/ptr.h:53
Base class providing an fe::Handle to the derived class.
Definition: Handled.h:209
Per-class participation non-RTTI fallback dynamic casting mechanism.
Definition: Castable.h:192