VRay SDK for C++
Loading...
Searching...
No Matches
vrayinterop.hpp
1#ifdef _VRAY_SDK_HPP_
2#ifndef _VRAY_INTEROP_HPP_
3#define _VRAY_INTEROP_HPP_
4
5#ifndef _MSC_VER
6#include <stdint.h>
7#endif
8
9namespace VRay {
10 namespace VUtils {
11 struct CharStringBuf {
12 static CharStringBuf* create(int size) {
13 return static_cast<CharStringBuf*>(Internal::CharStringBuf_create(size));
14 }
15
16 CharStringBuf* incRefCount() {
17 Internal::CharStringBuf_incRefCount(this);
18 return this;
19 }
20
21 void decRefCount() {
22 return Internal::CharStringBuf_decRefCount(this);
23 }
24
25 int getRefCount() {
26 return Internal::CharStringBuf_getRefCount(this);
27 }
28
29 char* resize(int s) {
30 return Internal::CharStringBuf_resize(this, s);
31 }
32
33 char* ptr() {
34 return Internal::CharStringBuf_getBuf(this);
35 }
36
37 private:
38 CharStringBuf();
39 ~CharStringBuf();
40 };
41
47 inline int vutils_strcpy_n(char *dest, const char *source, int destSize) {
48 if (destSize <= 0) return 0;
49 int len;
50 for (len = 0; (len<destSize - 1) && (source[len] != '\0'); len++) {
51 dest[len] = source[len];
52 }
53 dest[len] = '\0';
54 return len + 1;
55 }
56
62 inline int vutils_strlen_n(const char *str, int maxSize) {
63 int len = 0;
64 while (len<maxSize && str[len] != '\0') len++;
65 return len;
66 }
67
73 inline int vutils_strcat_n(char *dest, const char *source, int destSize) {
74 int len = vutils_strlen_n(dest, destSize);
75 return vutils_strcpy_n(dest + len, source, destSize - len);
76 }
77
84 inline int vutils_strcmp(const char *strA, const char *strB) {
85 const char *a = strA;
86 const char *b = strB;
87 while ((*a) != '\0' && (*a) == (*b)) { a++; b++; }
88 return (*a) - (*b);
89 }
90
98 inline int vutils_strcmp_n(const char *strA, const char *strB, int maxSize) {
99 const char *a = strA;
100 const char *b = strB;
101 int n = 1;
102 while ((*a) != '\0' && (*a) == (*b) && (n < maxSize)) { a++; b++; n++; }
103 return (*a) - (*b);
104 }
105
109 class CharString {
110 CharStringBuf *buf;
111 void freeMem(void) {
112 if (buf) buf->decRefCount();
113 buf = nullptr;
114 }
115
116 // Create a new buffer into which we can copy len+1 characters (the last one is the NUL char)
117 void splitBuffer(int len, int copyString) {
118 if (!buf) buf = CharStringBuf::create(len + 1); // There is no buffer currently, so create one
119 else if (buf->getRefCount()>1) { // Our buffer is shared with other objects, we must create a new one
120 CharStringBuf *tmpBuf = CharStringBuf::create(len + 1);
121 if (copyString)
122 vutils_strcpy_n(tmpBuf->ptr(), buf->ptr(), len + 1);
123 buf->decRefCount();
124 buf = tmpBuf;
125 }
126 else { // Buffer is not shared, we can modify it directly
127 buf->resize(len + 1);
128 }
129 }
130
131 // Set our buffer to the given one
132 void setBuffer(CharStringBuf *newBuffer) {
133 // Only do stuff if the new buffer is different from the old one.
134 if (newBuffer != buf) {
135 if (buf) buf->decRefCount(); // If there is a buffer already, release it
136 if (!newBuffer) buf = nullptr; // The new buffer is empty
137 else buf = newBuffer->incRefCount(); // The new buffer is not empty, so just reference it
138 }
139 }
140
141 // Make our buffer writeable (e.g. if shared, copy it)
142 void makeWriteable(void) {
143 if (!buf) return;
144 if (buf->getRefCount() <= 1) return; // This is the only copy of the buffer, it is safe to modify
145
146 // There are other references to the buffer, so we must clone it.
147 int len = length() + 1;
148 CharStringBuf *newBuffer = CharStringBuf::create(len + 1);
149 vutils_strcpy_n(newBuffer->ptr(), buf->ptr(), len + 1);
150 buf->decRefCount();
151 buf = newBuffer;
152 }
153
154 public:
156 CharString(void) :buf(nullptr) {}
157
159 CharString(const char *val) :buf(nullptr) {
160 if (val) {
161 int len = (int)strlen(val);
162 buf = CharStringBuf::create(len + 1);
163 char* wptr = buf->ptr();
164 if (wptr) vutils_strcpy_n(wptr, val, len + 1);
165 }
166 }
167
169 CharString(const CharString& r) :buf(nullptr) {
170 if (r.buf) buf = r.buf->incRefCount();
171 }
172
176 CharString(const char *str, int strLen) :buf(nullptr) {
177 set(str, strLen);
178 }
179
181 CharString(unsigned strLen) :buf(nullptr) {
182 buf = nullptr;
183 if (strLen) {
184 buf = CharStringBuf::create(strLen + 1);
185 char* wptr = buf->ptr();
186 if (wptr) {
187 memset(wptr, ' ', sizeof(char)*(strLen + 1));
188 wptr[strLen] = 0;
189 }
190 }
191 }
192
194 ~CharString(void) { freeMem(); }
195
197 const char* ptr(void) const {
198 return buf ? buf->ptr() : nullptr;
199 }
200
202 char* write_ptr(void) {
203 if (!buf) return nullptr;
204 makeWriteable();
205 return buf->ptr();
206 }
207
209 CharString& operator=(const char *newBuf) {
210 if (!newBuf) { freeMem(); return *this; }
211
212 int len = (int)strlen(newBuf);
213 splitBuffer(len, false);
214 char* wptr = buf->ptr();
215 if (wptr) vutils_strcpy_n(wptr, newBuf, len + 1);
216 return *this;
217 }
218
220 CharString& operator=(const CharString& str) {
221 setBuffer(str.buf);
222 return *this;
223 }
224
225 // strLen is without the trailing NUL character
226 void set(const char* str, int strLen) {
227 if (!str || strLen == 0) { freeMem(); return; }
228
229 splitBuffer(strLen, false);
230 char* wptr = buf->ptr();
231 if (wptr) vutils_strcpy_n(wptr, str, strLen + 1);
232 }
233
235 void set(const char* str) { *this = str; }
236
238 void set(const char* str1, const char* str2) {
239 int sz1 = (int)((str1) ? strlen(str1) : 0);
240 int sz2 = (int)((str2) ? strlen(str2) : 0);
241 if (!str1 || !str2 || !sz1 || !sz2) { freeMem(); return; }
242
243 splitBuffer(sz1 + sz2, false);
244 char* wptr = buf->ptr();
245 if (wptr) {
246 vutils_strcpy_n(wptr, str1, sz1 + sz2 + 1);
247 vutils_strcpy_n(wptr + sz1, str2, sz1 + sz2 + 1);
248 }
249 }
250
252 char operator[](int index) const { return buf->ptr()[index]; }
253
255 int length(void) const { return buf ? (int)strlen(buf->ptr()) : 0; }
256
260 void setLength(int newLen, char fillChar = ' ') {
261 if (newLen <= 0) { freeMem(); return; }
262
263 int len = length();
264 if (newLen == len) return;
265
266 splitBuffer(newLen, true);
267 char* wptr = buf->ptr();
268 if (wptr) {
269 if (newLen > len && fillChar != 0)
270 for (int i = len; i < newLen; i++)
271 wptr[i] = fillChar;
272 wptr[newLen] = 0;
273 }
274 }
275
277 void append(const char *str) {
278 if (!str) return;
279 if (!buf) *this = str;
280 else {
281 int strLen = (int)strlen(str);
282 int curLen = length();
283 splitBuffer(strLen + curLen, true);
284 char* wptr = buf->ptr();
285 if (wptr) vutils_strcat_n(wptr, str, curLen + strLen + 1);
286 }
287 }
288
290 void append(const CharString &str) {
291 append(str.ptr());
292 }
293
295 void append(const char *str, int length) {
296 if (!str) return;
297 if (!buf) set(str, length);
298 else {
299 int curLen = this->length();
300 splitBuffer(length + curLen, true);
301 char* wptr = buf->ptr();
302 if (wptr) vutils_strcat_n(wptr, str, curLen + length + 1);
303 }
304 }
305
307 void swap(CharString &str) noexcept {
308 CharStringBuf *temp = buf;
309 buf = str.buf;
310 str.buf = temp;
311 }
312
314 void clear(void) { freeMem(); }
315
317 bool empty(void) const { return (buf == nullptr) || (buf->ptr()[0] == 0); }
318 };
319
320 inline std::ostream& operator <<(std::ostream& stream, const CharString& str) {
321 const char* ptr = str.ptr();
322 stream << (ptr ? ptr : "<null string>");
323 return stream;
324 }
325
328 inline CharString operator+(const CharString &a, const CharString &b) {
329 CharString res(a);
330 res.append(b);
331 return res;
332 }
333
336 inline bool operator==(const CharString &a, const char *str) {
337 const char* ptr = a.ptr();
338 if (ptr == str) return true;
339 if (ptr == nullptr || str == nullptr) return false;
340 return strcmp(ptr, str) == 0;
341 }
342
345 inline bool operator!=(const CharString &a, const char *str) {
346 return !(a == str);
347 }
348
351 inline bool operator==(const CharString &a, const CharString &b) {
352 return a == b.ptr();
353 }
354
357 inline bool operator!=(const CharString &a, const CharString &b) {
358 return !(a == b);
359 }
360
363 inline bool operator<(const CharString &a, const CharString &b) {
364 const char* aptr = a.ptr();
365 const char* bptr = b.ptr();
366 if (bptr == nullptr) return false;
367 if (aptr == nullptr) return true;
368 return strcmp(aptr, bptr) < 0;
369 }
370
371 inline CharString makeCharString(const char *a, const char *b) {
372 CharString res(a);
373 res.append(b);
374 return res;
375 }
376
377 inline CharString makeCharString(const char *a, const char *b, const char *c) {
378 CharString res(a);
379 res.append(b);
380 res.append(c);
381 return res;
382 }
383
384 inline CharString makeCharString(const char *a, const char *b, const char *c, const char *d) {
385 CharString res(a);
386 res.append(b);
387 res.append(c);
388 res.append(d);
389 return res;
390 }
391
392 template<class T>
393 struct RefCounter {
394 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr);
395 void inc(int type);
396 int dec(int type);
397 T* allocMem(int type, int n);
398 void destroy(int type, T* ptr, int n);
399 static int unite(Type dataType, int counterType) {
400 return dataType | (counterType << 16);
401 }
402 private:
403 RefCounter();
404 ~RefCounter();
405 };
406
407 class Value;
408 template<class T> struct PtrArray;
409
410 typedef PtrArray<int> IntRefList;
411 typedef PtrArray<float> FloatRefList;
412 typedef PtrArray<Vector> VectorRefList;
413 typedef PtrArray<Color> ColorRefList;
414 typedef PtrArray<TraceTransform> TransformRefList;
415 typedef PtrArray<CharString> CharStringRefList;
416 typedef PtrArray<Value> ValueRefList;
417
418 class Object;
419
420 struct ObjectID {
421 InstanceId id; // Holds a plugin InstanceID
422 CharString subobj; // Holds a plugin output parameter name (plugin::outParamName)
423
424 explicit ObjectID(InstanceId id = 0)
425 : id(id)
426 {}
427
428 explicit ObjectID(const Plugin& plugin)
429 : id(plugin.getIntegerID())
430 {}
431
432 explicit ObjectID(const PluginRef& plugin)
433 : id(plugin.getIntegerID())
434 , subobj(plugin.getOutputName())
435 {}
436
437 bool operator==(const ObjectID &objID) {
438 return id == objID.id && subobj == objID.subobj;
439 }
440 bool operator!=(const ObjectID &objID) {
441 return id != objID.id || subobj != objID.subobj;
442 }
443 };
444
445 struct RuntimeValue {
446 Object *obj;
447 CharString valueName;
448
449 RuntimeValue() : obj() {}
450 RuntimeValue(const RuntimeValue& rv) = default;
451 RuntimeValue(RuntimeValue&& rv) = default;
452
453 bool operator==(const RuntimeValue& rv) {
454 return obj == rv.obj && valueName == rv.valueName;
455 }
456 bool operator!=(const RuntimeValue& rv) {
457 return obj != rv.obj || valueName != rv.valueName;
458 }
459 };
460
461 struct TracePoint {
462 double x, y, z;
463
464 TracePoint() {}
465 TracePoint(double x, double y, double z) : x(x), y(y), z(z) {}
466 explicit TracePoint(double v) : x(v), y(v), z(v) {}
467 TracePoint(const Vector &v) : x(v.x), y(v.y), z(v.z) {}
468 TracePoint(const TracePoint& tp) = default;
469
470 Vector toVector() const { return Vector(x, y, z); }
471
472 bool operator==(const TracePoint& tp) {
473 return x != tp.x && y == tp.y && z == tp.z;
474 }
475 bool operator!=(const TracePoint& tp) {
476 return x != tp.x || y != tp.y || z != tp.z;
477 }
478 std::string toString() const;
479 };
480
481 inline std::ostream& operator <<(std::ostream& stream, const TracePoint& vector) {
482 stream << "Vector(" << vector.x << ", " << vector.y << ", " << vector.z << ")";
483 return stream;
484 }
485
486 inline std::string TracePoint::toString() const {
487 std::ostringstream stream;
488 stream << *this;
489 return stream.str();
490 }
491
492 struct TraceTransform {
493 Matrix m;
494 int padding;
495 TracePoint offs;
496
497 TraceTransform() {}
498 explicit TraceTransform(float f) : m(f), offs(0) {}
499 TraceTransform(const Transform& t) : m(t.matrix), offs(t.offset) {}
500 TraceTransform(const TraceTransform& tt) = default;
501
502 Transform toTransform() const { return Transform(m, offs.toVector()); }
503
504 bool operator==(const TraceTransform& tt) {
505 return m == tt.m && offs == tt.offs;
506 }
507 bool operator!=(const TraceTransform& tt) {
508 return m != tt.m || offs != tt.offs;
509 }
510 std::string toString() const;
511 };
512
513 inline std::ostream& operator <<(std::ostream& stream, const TraceTransform& transform) {
514 stream << "Transform(" << transform.m << ", " << transform.offs << ")";
515 return stream;
516 }
517
518 inline std::string TraceTransform::toString() const {
519 std::ostringstream stream;
520 stream << *this;
521 return stream.str();
522 }
523
525 enum VALUE_TYPE {
526 UNKNOWN = 0,
527 NUMBER,
528 LIST,
529 VECTOR,
530 MATRIX,
531 COLOR,
532 ACOLOR,
533 TRANSFORM,
534 LISTVECTOR,
535 LISTINT,
536 LISTCOLOR,
537 LISTFLOAT,
538 STRING,
539 OBJECT,
540 OBJECTID,
541 RUNTIMEVALUE,
542 LISTSTRING,
543 //OBJECT_NAME
544 };
545
546 template<>
547 struct RefCounter<int> {
548 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
549 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_INT, type), callbackFn, callbackData));
550 }
551
552 void inc(int type) {
553 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_INT, type));
554 }
555
556 int dec(int type) {
557 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_INT, type));
558 }
559
560 int* allocMem(int type, int n) {
561 return static_cast<int*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_INT, type), n));
562 }
563
564 void destroy(int type, int* ptr, int n) {
565 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_INT, type), ptr, n);
566 }
567 };
568
569 template<>
570 struct RefCounter<float> {
571 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
572 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_FLOAT, type), callbackFn, callbackData));
573 }
574
575 void inc(int type) {
576 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_FLOAT, type));
577 }
578
579 int dec(int type) {
580 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_FLOAT, type));
581 }
582
583 float* allocMem(int type, int n) {
584 return static_cast<float*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_FLOAT, type), n));
585 }
586
587 void destroy(int type, float* ptr, int n) {
588 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_FLOAT, type), ptr, n);
589 }
590 };
591
592 template<>
593 struct RefCounter<Vector> {
594 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
595 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_VECTOR, type), callbackFn, callbackData));
596 }
597
598 void inc(int type) {
599 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_VECTOR, type));
600 }
601
602 int dec(int type) {
603 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_VECTOR, type));
604 }
605
606 Vector* allocMem(int type, int n) {
607 return static_cast<Vector*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_VECTOR, type), n));
608 }
609
610 void destroy(int type, Vector* ptr, int n) {
611 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_VECTOR, type), ptr, n);
612 }
613 };
614
615 template<>
616 struct RefCounter<Color> {
617 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
618 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_COLOR, type), callbackFn, callbackData));
619 }
620
621 void inc(int type) {
622 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_COLOR, type));
623 }
624
625 int dec(int type) {
626 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_COLOR, type));
627 }
628
629 Color* allocMem(int type, int n) {
630 return static_cast<Color*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_COLOR, type), n));
631 }
632
633 void destroy(int type, Color* ptr, int n) {
634 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_COLOR, type), ptr, n);
635 }
636 };
637
638 template<>
639 struct RefCounter<TraceTransform> {
640 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
641 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_TRANSFORM, type), callbackFn, callbackData));
642 }
643
644 void inc(int type) {
645 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_TRANSFORM, type));
646 }
647
648 int dec(int type) {
649 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_TRANSFORM, type));
650 }
651
652 TraceTransform* allocMem(int type, int n) {
653 return static_cast<TraceTransform*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_TRANSFORM, type), n));
654 }
655
656 void destroy(int type, TraceTransform* ptr, int n) {
657 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_TRANSFORM, type), ptr, n);
658 }
659 };
660
661 template<>
662 struct RefCounter<CharString> {
663 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
664 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_STRING, type), callbackFn, callbackData));
665 }
666
667 void inc(int type) {
668 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_STRING, type));
669 }
670
671 int dec(int type) {
672 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_STRING, type));
673 }
674
675 CharString* allocMem(int type, int n) {
676 return static_cast<CharString*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_STRING, type), n));
677 }
678
679 void destroy(int type, CharString* ptr, int n) {
680 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_STRING, type), ptr, n);
681 }
682 };
683
684 template<>
685 struct RefCounter<Value> {
686 static RefCounter* create(int type, Internal::PtrArrayCustomCallbackFn callbackFn = nullptr, void* callbackData = nullptr) {
687 return static_cast<RefCounter*>(Internal::RefCounter_create(RefCounter<void>::unite(TYPE_LIST, type), callbackFn, callbackData));
688 }
689
690 void inc(int type) {
691 Internal::RefCounter_increment(this, RefCounter<void>::unite(TYPE_LIST, type));
692 }
693
694 int dec(int type) {
695 return Internal::RefCounter_decrement(this, RefCounter<void>::unite(TYPE_LIST, type));
696 }
697
698 Value* allocMem(int type, int n) {
699 return static_cast<Value*>(Internal::RefCounter_allocMem(this, RefCounter<void>::unite(TYPE_LIST, type), n));
700 }
701
702 void destroy(int type, Value* ptr, int n) {
703 Internal::RefCounter_release(this, RefCounter<void>::unite(TYPE_LIST, type), ptr, n);
704 }
705 };
706
708 template<class T>
709 struct PtrArray {
711 PtrArray(void) { ptr = nullptr; refCounter = nullptr; length = 0; }
712
714 PtrArray(const PtrArray &p) { copy(p); }
715
717 PtrArray(PtrArray &&p) noexcept { m0ve(std::move(p)); }
718
720 PtrArray& operator=(const PtrArray &p) {
721 if (this!=&p) {
722 freeMem();
723 copy(p);
724 }
725 return *this;
726 }
727
729 PtrArray& operator=(PtrArray &&p) noexcept {
730 if (this != &p) {
731 freeMem();
732 m0ve(std::move(p));
733 }
734 return *this;
735 }
736
738 bool operator==(const PtrArray&& p) {
739 if (ptr == p.ptr) return true;
740 if (!ptr || !p.ptr) return false;
741 for (int i = 0; i < length; ++i) {
742 if (ptr[i] != p.ptr[i]) return false;
743 }
744 return true;
745 }
746
748 explicit PtrArray(int num) { allocArray(num); }
749
753 PtrArray(T *ptr, int len) { init(ptr, len); }
754
757 template<int len>
758 explicit PtrArray(T (&arr)[len]) { init(arr, len); }
759
761 ~PtrArray(void) { freeMem(); }
762
764 T& operator[](int i) { return ptr[i]; }
765
767 const T& operator[](int i) const { return ptr[i]; }
768
770 bool operator!(void) const { return (ptr == nullptr); }
771
773 operator T*(void) { return ptr; }
774
776 operator const T*(void) const { return ptr; }
777
782 void init(T *ptr, int len) {
783 type = Internal::ownerTypeNone;
784 this->ptr = ptr;
785 refCounter = nullptr;
786 length = len;
787 }
788
790 void freeMem(void) {
791 if (refCounter) { // We count the references.
792 if (refCounter->dec(type) == 0) { // This was the last reference to it - delete it.
793 refCounter->destroy(type, ptr, length);
794 }
795 }
796 refCounter = nullptr;
797 ptr = nullptr;
798 length = 0;
799 type = Internal::ownerTypeNone;
800 }
801
803 T* get(void) { return ptr; }
804 const T* get(void) const { return ptr; }
805
807 int size(void) const { return length; }
808 int count(void) const { return length; }
809
810 std::string toString() const;
811
812 private:
813 T *ptr;
814 RefCounter<T> *refCounter;
815 int length;
816
817 Internal::PtrArrayOwnershipType type;
818
825 PtrArray(T *ptr, int len, Internal::PtrArrayCustomCallbackFn callbackFn, void* callbackData) { init(ptr, len, callbackFn, callbackData); }
826
833 void init(T *ptr, int len, Internal::PtrArrayCustomCallbackFn callbackFn, void* callbackData) {
834 type = Internal::ownerTypeCallback;
835 this->ptr = ptr;
836 refCounter = RefCounter<T>::create(type, callbackFn, callbackData);
837 length = len;
838 }
839
840 void copy(const PtrArray &p) {
841 ptr = p.ptr;
842 refCounter = p.refCounter;
843 length = p.length;
844 type = p.type;
845 if (refCounter) refCounter->inc(type);
846 }
847
848 void m0ve(PtrArray&& p) {
849 ptr = p.ptr;
850 refCounter = p.refCounter;
851 length = p.length;
852 type = p.type;
853
854 p.ptr = nullptr;
855 p.refCounter = nullptr;
856 p.length = 0;
857 p.type = Internal::ownerTypeNone;
858 }
859
860 void allocArray(int num) {
861 type = Internal::ownerTypeOwnMem;
862 length = num;
863 refCounter = RefCounter<T>::create(type);
864 ptr = refCounter->allocMem(type, length);
865 }
866 };
867
868 template<class T>
869 inline std::ostream& operator <<(std::ostream& stream, const PtrArray<T>& list) {
870 stream << "[";
871 if (list && list.count() > 0) {
872 int i = 0;
873 while (i < list.count() - 1)
874 stream << list[i++] << ", ";
875 stream << list[i];
876 }
877 stream << ']';
878 return stream;
879 }
880
881 template<class T>
882 inline std::string PtrArray<T>::toString() const {
883 std::ostringstream stream;
884 stream << *this;
885 return stream.str();
886 }
887
888 class Value {
889 struct StringValue {
890 CharString str;
891 CharString scenePath;
892 CharStringRefList stringList;
893 };
894
895 size_t data[8];
896 VALUE_TYPE valueType;
897
898 template<typename TYPE> TYPE& as() { return *reinterpret_cast<TYPE *>(data); }
899 template<typename TYPE> const TYPE& as() const { return *reinterpret_cast<const TYPE *>(data); }
900
901 // common for copy constructor and operator=
902 void copy(const Value &other)
903 {
904 // Make sure destroy is called (directly or from a setXXX method).
905 // If it is not called there would be memory leaks!
906
907 switch (other.valueType) {
908 case NUMBER:
909 setDouble(other.getDouble());
910 break;
911 case VECTOR:
912 setVector(other.getTracePoint());
913 break;
914 case MATRIX:
915 setMatrix(other.getMatrix());
916 break;
917 case COLOR:
918 setColor(other.getColor());
919 break;
920 case ACOLOR:
921 setAColor(other.getAColor());
922 break;
923 case TRANSFORM:
924 setTransform(other.getTransform());
925 break;
926 case OBJECT:
927 setObject(other.getObject());
928 break;
929 case OBJECTID:
930 setObjectID(other.getObjectID());
931 break;
932 case LIST:
933 setList(other.getList());
934 break;
935 case LISTINT:
936 setListInt(other.getListInt());
937 break;
938 case LISTFLOAT:
939 setListFloat(other.getListFloat());
940 break;
941 case LISTVECTOR:
942 setListVector(other.getListVector());
943 break;
944 case LISTCOLOR:
945 setListColor(other.getListColor());
946 break;
947 case LISTSTRING:
948 setListString(other.getListString());
949 //setScenePath(other.getScenePath());
950 break;
951 case STRING:
952 //case OBJECT_NAME:
953 setString(other.getString());
954 //setScenePath(other.getScenePath());
955 break;
956 case RUNTIMEVALUE:
957 setRuntimeValue(other.getRuntimeValue());
958 break;
959 case UNKNOWN:
960 destroy();
961 valueType = UNKNOWN;
962 break;
963 }
964 }
965
966 void destroy() {
967 switch (valueType) {
968 case UNKNOWN:
969 case NUMBER:
970 case VECTOR:
971 case MATRIX:
972 case COLOR:
973 case ACOLOR:
974 case TRANSFORM:
975 case OBJECT:
976 /* POD, no destructor */
977 break;
978 case OBJECTID:
979 as<ObjectID>().~ObjectID();
980 break;
981 case LIST:
982 as<ValueRefList>().~PtrArray();
983 break;
984 case LISTINT:
985 as<IntRefList>().~PtrArray();
986 break;
987 case LISTFLOAT:
988 as<FloatRefList>().~PtrArray();
989 break;
990 case LISTVECTOR:
991 as<VectorRefList>().~PtrArray();
992 break;
993 case LISTCOLOR:
994 as<ColorRefList>().~PtrArray();
995 break;
996 case LISTSTRING:
997 as<StringValue>().stringList.~PtrArray();
998 as<StringValue>().scenePath.~CharString();
999 break;
1000 case STRING:
1001 //case OBJECT_NAME:
1002 as<StringValue>().str.~CharString();
1003 as<StringValue>().scenePath.~CharString();
1004 break;
1005 case RUNTIMEVALUE:
1006 as<RuntimeValue>().~RuntimeValue();
1007 break;
1008 }
1009 }
1010
1011 public:
1012 explicit Value() {
1013 valueType = UNKNOWN;
1014 }
1015
1016 explicit Value(double val) {
1017 valueType = NUMBER;
1018 new (data) double(val);
1019 }
1020
1021 explicit Value(const TracePoint &v) {
1022 valueType = VECTOR;
1023 new (data) TracePoint(v);
1024 }
1025
1026 explicit Value(const Vector &v) {
1027 valueType = VECTOR;
1028 new (data) TracePoint(v);
1029 }
1030
1031 explicit Value(const Matrix &mat) {
1032 valueType = MATRIX;
1033 new (data) Matrix(mat);
1034 }
1035
1036 explicit Value(const Color &col) {
1037 valueType = COLOR;
1038 new (data) Color(col);
1039 }
1040
1041 explicit Value(const AColor &acol) {
1042 valueType = ACOLOR;
1043 new (data) AColor(acol);
1044 }
1045
1046 explicit Value(const TraceTransform &transform) {
1047 valueType = TRANSFORM;
1048 new (data) TraceTransform(transform);
1049 }
1050
1051 explicit Value(Object *obj) {
1052 valueType = OBJECT;
1053 new (data) Object*(obj);
1054 }
1055
1056 explicit Value(const ObjectID &id) {
1057 valueType = OBJECTID;
1058 new (data) ObjectID(id);
1059 }
1060
1061 explicit Value(const ValueRefList &lst) {
1062 valueType = LIST;
1063 new (data) ValueRefList(lst);
1064 }
1065
1066 explicit Value(const RuntimeValue &rtVal) {
1067 valueType = RUNTIMEVALUE;
1068 new (data) RuntimeValue(rtVal);
1069 }
1070
1071 explicit Value(const CharString &str) {
1072 valueType = STRING;
1073 new (&(as<StringValue>().str)) CharString(str);
1074 new (&(as<StringValue>().scenePath)) CharString();
1075 }
1076
1077 //explicit Value(const CharString &str, VALUE_TYPE customType) {
1078 // valueType = OBJECT_NAME;
1079 // new (&(as<StringValue>().str)) CharString(str);
1080 // new (&(as<StringValue>().scenePath)) CharString();
1081 //}
1082
1083 explicit Value(const VectorRefList &list) {
1084 valueType = LISTVECTOR;
1085 new (data) VectorRefList(list);
1086 }
1087
1088 explicit Value(const ColorRefList &list) {
1089 valueType = LISTCOLOR;
1090 new (data) ColorRefList(list);
1091 }
1092
1093 explicit Value(const FloatRefList &list) {
1094 valueType = LISTFLOAT;
1095 new (data) FloatRefList(list);
1096 }
1097
1098 explicit Value(const IntRefList &list) {
1099 valueType = LISTINT;
1100 new (data) IntRefList(list);
1101 }
1102
1103 explicit Value(const CharStringRefList &list) {
1104 valueType = LISTSTRING;
1105 new (&(as<StringValue>().stringList)) CharStringRefList(list);
1106 new (&(as<StringValue>().scenePath)) CharString();
1107 }
1108
1109 explicit Value(const Plugin &plugin) {
1110 valueType = OBJECTID;
1111 new (data) ObjectID(plugin);
1112 }
1113
1114 explicit Value(const PluginRef& plugin) {
1115 valueType = OBJECTID;
1116 new (data) ObjectID(plugin);
1117 }
1118
1119 Value(const Value &v) {
1120 valueType = UNKNOWN;
1121 copy(v);
1122 }
1123
1124 Value &operator=(const Value &v) {
1125 copy(v);
1126 return *this;
1127 }
1128
1129 bool operator==(const Value &v) {
1130 if (valueType != v.valueType) return false;
1131 switch (valueType) {
1132 case NUMBER:
1133 return as<double>() == v.as<double>();
1134 case VECTOR:
1135 return as<TracePoint>() == v.as<TracePoint>();
1136 case MATRIX:
1137 return as<Matrix>() == v.as<Matrix>();
1138 case COLOR:
1139 return as<Color>() == v.as<Color>();
1140 case ACOLOR:
1141 return as<AColor>() == v.as<AColor>();
1142 case TRANSFORM:
1143 return as<TraceTransform>() == v.as<TraceTransform>();
1144 case OBJECT:
1145 return as<Object*>() == v.as<Object*>();
1146 case OBJECTID:
1147 return as<ObjectID>() == v.as<ObjectID>();
1148 case LIST:
1149 return as<ValueRefList>() == v.as<ValueRefList>();
1150 case LISTINT:
1151 return as<IntRefList>() == v.as<IntRefList>();
1152 case LISTFLOAT:
1153 return as<FloatRefList>() == v.as<FloatRefList>();
1154 case LISTVECTOR:
1155 return as<VectorRefList>() == v.as<VectorRefList>();
1156 case LISTCOLOR:
1157 return as<ColorRefList>() == v.as<ColorRefList>();
1158 case LISTSTRING:
1159 return as<StringValue>().stringList == v.as<StringValue>().stringList;
1160 case STRING:
1161 return as<StringValue>().str == v.as<StringValue>().str;
1162 case RUNTIMEVALUE:
1163 return as<RuntimeValue>() == v.as<RuntimeValue>();
1164 case UNKNOWN:
1165 return false;
1166 }
1167 }
1168
1169 bool operator!=(const Value& v) {
1170 return !operator==(v);
1171 }
1172
1173 ~Value() {
1174 destroy();
1175 }
1176
1179 VALUE_TYPE getValueType() const {
1180 return valueType;
1181 }
1182
1183 // Pair
1184 void setRuntimeValue(const RuntimeValue &rtVal) {
1185 destroy();
1186 valueType = RUNTIMEVALUE;
1187 new (data) RuntimeValue(rtVal);
1188 }
1189
1190 RuntimeValue getRuntimeValue() const {
1191 if (valueType == RUNTIMEVALUE) {
1192 return as<RuntimeValue>();
1193 }
1194
1195 return RuntimeValue();
1196 }
1197
1198 void setDouble(double val) {
1199 destroy();
1200 valueType = NUMBER;
1201 new (data) double(val);
1202 }
1203
1204 double getDouble() const {
1205 if (valueType == NUMBER) {
1206 return as<double>();
1207 }
1208
1209 return 0.0;
1210 }
1211
1212 void setList(const ValueRefList &list) {
1213 destroy();
1214 valueType = LIST;
1215 new (data) ValueRefList(list);
1216 }
1217
1218 ValueRefList getList() const {
1219 if (valueType == LIST) {
1220 return as<ValueRefList>();
1221 }
1222
1223 return ValueRefList();
1224 }
1225
1226 void setListVector(const VectorRefList &list) {
1227 destroy();
1228 valueType = LISTVECTOR;
1229 new (data) VectorRefList(list);
1230 }
1231
1232 VectorRefList getListVector() const {
1233 if (valueType == LISTVECTOR) {
1234 return as<VectorRefList>();
1235 }
1236
1237 return VectorRefList();
1238 }
1239
1240 void setListInt(const IntRefList &list) {
1241 destroy();
1242 valueType = LISTINT;
1243 new (data) IntRefList(list);
1244 }
1245
1246 IntRefList getListInt() const {
1247 if (valueType == LISTINT) {
1248 return as<IntRefList>();
1249 }
1250
1251 return IntRefList();
1252 }
1253
1254 void setListColor(const ColorRefList &list) {
1255 destroy();
1256 valueType = LISTCOLOR;
1257 new (data) ColorRefList(list);
1258 }
1259
1260 ColorRefList getListColor() const {
1261 if (valueType == LISTCOLOR) {
1262 return as<ColorRefList>();
1263 }
1264
1265 return ColorRefList();
1266 }
1267
1268 void setListFloat(const FloatRefList &list) {
1269 destroy();
1270 valueType = LISTFLOAT;
1271 new (data) FloatRefList(list);
1272 }
1273
1274 FloatRefList getListFloat() const {
1275 if (valueType == LISTFLOAT) {
1276 return as<FloatRefList>();
1277 }
1278
1279 return FloatRefList();
1280 }
1281
1282 void setListString(const CharStringRefList &list) {
1283 destroy();
1284 valueType = LISTSTRING;
1285 new (&(as<StringValue>().stringList)) CharStringRefList(list);
1286 new (&(as<StringValue>().scenePath)) CharString();
1287 }
1288
1289 CharStringRefList getListString() const {
1290 if (valueType == LISTSTRING) {
1291 return as<StringValue>().stringList;
1292 }
1293
1294 return CharStringRefList();
1295 }
1296
1297 void setObject(Object *obj) {
1298 destroy();
1299 valueType = OBJECT;
1300 new (data) Object*(obj);
1301 }
1302
1303 Object* getObject() const {
1304 if (valueType == OBJECT) {
1305 return as<Object*>();
1306 }
1307
1308 return nullptr;
1309 }
1310
1311 // Plugin
1312 void setObjectID(const ObjectID &id) {
1313 destroy();
1314 valueType = OBJECTID;
1315 new (data) ObjectID(id);
1316 }
1317
1318 ObjectID getObjectID() const {
1319 if (valueType == OBJECTID) {
1320 return as<ObjectID>();
1321 }
1322
1323 return ObjectID();
1324 }
1325
1326 Vector getVector() const {
1327 if (valueType == VECTOR) {
1328 const TracePoint &pt = as<TracePoint>();
1329 return Vector(pt.x, pt.y, pt.z);
1330 }
1331
1332 return Vector(0.0f);
1333 }
1334
1335 void setVector(const TracePoint &v) {
1336 destroy();
1337 valueType = VECTOR;
1338 new (data) TracePoint(v);
1339 }
1340
1341 void setVector(const Vector &v) {
1342 destroy();
1343 valueType = VECTOR;
1344 new (data) TracePoint(v);
1345 }
1346
1347 TracePoint getTracePoint() const {
1348 if (valueType == VECTOR) {
1349 return as<TracePoint>();
1350 }
1351
1352 return TracePoint(0.0f);
1353 }
1354
1355 void setTracePoint(const TracePoint &v) {
1356 destroy();
1357 valueType = VECTOR;
1358 new (data) TracePoint(v);
1359 }
1360
1361 Matrix getMatrix() const {
1362 if (valueType == MATRIX || valueType == TRANSFORM) {
1363 return as<Matrix>();
1364 }
1365
1366 return Matrix(0);
1367 }
1368
1369 void setMatrix(const Matrix &v) {
1370 destroy();
1371 valueType = MATRIX;
1372 new (data) Matrix(v);
1373 }
1374
1375 Color getColor() const {
1376 if (valueType == COLOR) {
1377 return as<Color>();
1378 }
1379
1380 return Color(0.0f);
1381 }
1382
1383 void setColor(const Color &v) {
1384 destroy();
1385 valueType = COLOR;
1386 new (data) Color(v);
1387 }
1388
1389 AColor getAColor() const {
1390 if (valueType == ACOLOR) {
1391 return as<AColor>();
1392 } else if (valueType == COLOR) {
1393 return AColor(as<Color>());
1394 }
1395
1396 return AColor(0.0f);
1397 }
1398
1399 void setAColor(const AColor &v) {
1400 destroy();
1401 valueType = ACOLOR;
1402 new (data) AColor(v);
1403 }
1404
1405 void setString(const CharString &str) {
1406 destroy();
1407 valueType = STRING;
1408 new (&(as<StringValue>().str)) CharString(str);
1409 new (&(as<StringValue>().scenePath)) CharString();
1410 }
1411
1412 CharString getString() const {
1413 if (valueType == STRING) {
1414 return as<StringValue>().str;
1415 }
1416
1417 return CharString();
1418 }
1419
1420 void setTransform(const TraceTransform &tr) {
1421 destroy();
1422 valueType = TRANSFORM;
1423 new (data) TraceTransform(tr);
1424 }
1425
1426 TraceTransform getTransform() const {
1427 if (valueType == TRANSFORM) {
1428 return as<TraceTransform>();
1429 } else if (valueType == MATRIX) {
1430 TraceTransform t;
1431 t.m = as<Matrix>();
1432 t.offs = TracePoint(0.0);
1433 return t;
1434 }
1435
1436 return TraceTransform(0);
1437 }
1438
1439
1440 // AppSDK PluginRef
1441 const PluginRef getPlugin(VRayRenderer& renderer) const {
1442 struct PluginRefWrap : public PluginRef {
1443 PluginRefWrap(VRayRenderer& renderer, InstanceId id, const char* output)
1444 : PluginRef(renderer, id, output) { }
1445 };
1446 if (valueType == OBJECTID) {
1447 ObjectID objId = as<ObjectID>();
1448 return PluginRefWrap(renderer, objId.id, objId.subobj.ptr());
1449 }
1450 return PluginRefWrap(renderer, 0, nullptr);
1451 }
1452
1453 void setPlugin(const PluginRef& plugin) {
1454 destroy();
1455 valueType = OBJECTID;
1456 new (data) ObjectID(plugin);
1457 }
1458 };
1459
1460 inline std::ostream& operator <<(std::ostream& stream, const Value& value) {
1461 switch (value.getValueType()) {
1462 case NUMBER:
1463 stream << value.getDouble();
1464 break;
1465 case VECTOR:
1466 stream << value.getVector();
1467 break;
1468 case MATRIX:
1469 stream << value.getMatrix();
1470 break;
1471 case COLOR:
1472 stream << value.getColor();
1473 break;
1474 case ACOLOR:
1475 stream << value.getAColor();
1476 break;
1477 case TRANSFORM:
1478 stream << value.getTransform().toTransform();
1479 break;
1480 case OBJECT:
1481 stream << "<Scene Parser Object>";
1482 break;
1483 case OBJECTID: {
1484 const ObjectID& objId = value.getObjectID();
1485 stream << "ObjectID<" << value.getObjectID().id;
1486 if (!objId.subobj.empty())
1487 stream << ", " << objId.subobj.ptr();
1488 stream << ">";
1489 } break;
1490 case LIST:
1491 stream << value.getList();
1492 break;
1493 case LISTINT:
1494 stream << value.getListInt();
1495 break;
1496 case LISTFLOAT:
1497 stream << value.getListFloat();
1498 break;
1499 case LISTVECTOR:
1500 stream << value.getListVector();
1501 break;
1502 case LISTCOLOR:
1503 stream << value.getListColor();
1504 break;
1505 case LISTSTRING:
1506 stream << value.getListString();
1507 break;
1508 case STRING:
1509 stream << value.getString();
1510 break;
1511 case RUNTIMEVALUE:
1512 stream << "<Scene Parser Runtime Value>";
1513 break;
1514 case UNKNOWN:
1515 stream << "<Unknown Value>";
1516 break;
1517 }
1518 return stream;
1519 }
1520
1521 }
1522#undef DATAPTR
1523}
1524
1525#endif // _VRAY_INTEROP_HPP_
1526
1527#else // _VRAY_SDK_HPP_
1528
1529# ifndef VRAY_SDK_INTEROPERABILITY
1530# define VRAY_SDK_INTEROPERABILITY
1531# endif
1532# include "vraysdk.hpp"
1533
1534#endif // _VRAY_SDK_HPP_