RayRenderObject::RayRenderObject(RTCDevice device, int senderId, const std::string &senderPort, Object::const_ptr container, Object::const_ptr geometry, Object::const_ptr normals, Object::const_ptr texture) : vistle::RenderObject(senderId, senderPort, container, geometry, normals, texture) , data(new ispc::RenderObjectData) { data->device = device; data->scene = nullptr; data->geomID = RTC_INVALID_GEOMETRY_ID; data->instID = RTC_INVALID_GEOMETRY_ID; data->spheres = nullptr; data->primitiveFlags = nullptr; data->indexBuffer = nullptr; data->texWidth = 0; data->texData = nullptr; data->texCoords = nullptr; data->lighted = 1; data->hasSolidColor = hasSolidColor; data->perPrimitiveMapping = 0; data->normalsPerPrimitiveMapping = 0; for (int c=0; c<3; ++c) { data->normalTransform[c].x = c==0 ? 1 : 0; data->normalTransform[c].y = c==1 ? 1 : 0; data->normalTransform[c].z = c==2 ? 1 : 0; } for (int c=0; c<3; ++c) { data->normals[c] = nullptr; } for (int c=0; c<4; ++c) { data->solidColor[c] = solidColor[c]; } if (this->texture) { if (this->texture->guessMapping(geometry) == DataBase::Element) data->perPrimitiveMapping = 1; data->texWidth = this->texture->getWidth(); data->texData = this->texture->pixels().data(); data->texCoords = &this->texture->coords()[0]; } if (geometry->isEmpty()) { return; } data->scene = rtcNewScene(data->device); rtcSetSceneFlags(data->scene, RTC_SCENE_FLAG_NONE); rtcSetSceneBuildQuality(data->scene, RTC_BUILD_QUALITY_MEDIUM); RTCGeometry geom = 0; bool useNormals = true; if (auto tri = Triangles::as(geometry)) { Index numElem = tri->getNumElements(); geom = rtcNewGeometry (data->device, RTC_GEOMETRY_TYPE_TRIANGLE); rtcSetGeometryBuildQuality(geom,RTC_BUILD_QUALITY_MEDIUM); rtcSetGeometryTimeStepCount(geom,1); std::cerr << "Tri: #: " << tri->getNumElements() << ", #corners: " << tri->getNumCorners() << ", #coord: " << tri->getNumCoords() << std::endl; Vertex* vertices = (Vertex*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_VERTEX,0,RTC_FORMAT_FLOAT3,4*sizeof(float),tri->getNumCoords()); for (Index i=0; i<tri->getNumCoords(); ++i) { vertices[i].x = tri->x()[i]; vertices[i].y = tri->y()[i]; vertices[i].z = tri->z()[i]; } //data->indexBuffer = new Triangle[numElem]; //rtcSetSharedGeometryBuffer(geom_0,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,data->indexBuffer,0,sizeof(Triangle),numElem); Triangle* triangles = (Triangle*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,sizeof(Triangle),numElem); data->indexBuffer = triangles; if (tri->getNumCorners() == 0) { for (Index i=0; i<numElem; ++i) { triangles[i].v0 = i*3; triangles[i].v1 = i*3+1; triangles[i].v2 = i*3+2; triangles[i].elem = i; } } else { for (Index i=0; i<numElem; ++i) { triangles[i].v0 = tri->cl()[i*3]; triangles[i].v1 = tri->cl()[i*3+1]; triangles[i].v2 = tri->cl()[i*3+2]; triangles[i].elem = i; } } } else if (auto poly = Polygons::as(geometry)) { Index ntri = poly->getNumCorners()-2*poly->getNumElements(); vassert(ntri >= 0); geom = rtcNewGeometry (data->device, RTC_GEOMETRY_TYPE_TRIANGLE); rtcSetGeometryBuildQuality(geom,RTC_BUILD_QUALITY_MEDIUM); rtcSetGeometryTimeStepCount(geom,1); //std::cerr << "Poly: #tri: " << poly->getNumCorners()-2*poly->getNumElements() << ", #coord: " << poly->getNumCoords() << std::endl; Vertex* vertices = (Vertex*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_VERTEX,0,RTC_FORMAT_FLOAT3,4*sizeof(float),poly->getNumCoords()); for (Index i=0; i<poly->getNumCoords(); ++i) { vertices[i].x = poly->x()[i]; vertices[i].y = poly->y()[i]; vertices[i].z = poly->z()[i]; } //data->indexBuffer = new Triangle[ntri]; //rtcSetSharedGeometryBuffer(geom,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,data->indexBuffer,0,sizeof(Triangle),ntri); Triangle* triangles = (Triangle*) rtcSetNewGeometryBuffer(geom,RTC_BUFFER_TYPE_INDEX,0,RTC_FORMAT_UINT3,sizeof(Triangle),ntri); data->indexBuffer = triangles; Index t = 0; for (Index i=0; i<poly->getNumElements(); ++i) { const Index start = poly->el()[i]; const Index end = poly->el()[i+1]; const Index nvert = end-start; const Index last = end-1; for (Index v=0; v<nvert-2; ++v) { triangles[t].elem = i; const Index v2 = v/2; if (v%2) { triangles[t].v0 = poly->cl()[last-v2]; triangles[t].v1 = poly->cl()[start+v2+1]; triangles[t].v2 = poly->cl()[last-v2-1]; } else { triangles[t].v0 = poly->cl()[start+v2]; triangles[t].v1 = poly->cl()[start+v2+1]; triangles[t].v2 = poly->cl()[last-v2]; } ++t; } } vassert(t == ntri); } else if (auto sph = Spheres::as(geometry)) { useNormals = false; Index nsph = sph->getNumSpheres(); //std::cerr << "Spheres: #sph: " << nsph << std::endl; data->spheres = new ispc::Sphere[nsph]; auto x = &sph->x()[0]; auto y = &sph->y()[0]; auto z = &sph->z()[0]; auto r = &sph->r()[0]; auto s = data->spheres; for (Index i=0; i<nsph; ++i) { s[i].p.x = x[i]; s[i].p.y = y[i]; s[i].p.z = z[i]; s[i].r = r[i]; } geom = newSpheres(data.get(), nsph); } else if (auto point = Points::as(geometry)) { Index np = point->getNumPoints(); //std::cerr << "Points: #sph: " << np << std::endl; data->spheres = new ispc::Sphere[np]; auto x = &point->x()[0]; auto y = &point->y()[0]; auto z = &point->z()[0]; auto s = data->spheres; for (Index i=0; i<np; ++i) { s[i].p.x = x[i]; s[i].p.y = y[i]; s[i].p.z = z[i]; s[i].r = pointSize; } data->lighted = 0; geom = newSpheres(data.get(), np); } else if (auto line = Lines::as(geometry)) { Index nStrips = line->getNumElements(); Index nPoints = line->getNumCorners(); std::cerr << "Lines: #strips: " << nStrips << ", #corners: " << nPoints << std::endl; data->primitiveFlags = new unsigned int[nPoints]; data->spheres = new ispc::Sphere[nPoints]; auto el = &line->el()[0]; auto cl = &line->cl()[0]; auto x = &line->x()[0]; auto y = &line->y()[0]; auto z = &line->z()[0]; auto s = data->spheres; auto p = data->primitiveFlags; Index idx=0; for (Index strip=0; strip<nStrips; ++strip) { const Index begin = el[strip], end = el[strip+1]; for (Index c=begin; c<end; ++c) { Index i = cl[c]; s[idx].p.x = x[i]; s[idx].p.y = y[i]; s[idx].p.z = z[i]; s[idx].r = pointSize; p[idx] = ispc::PFNone; if (c+1 != end) p[idx] |= ispc::PFCone; p[idx] |= ispc::PFStartSphere; ++idx; } } vassert(idx == nPoints); data->lighted = 0; geom = newTubes(data.get(), nPoints-1); } else if (auto tube = Tubes::as(geometry)) { useNormals= false; Index nStrips = tube->getNumTubes(); Index nPoints = tube->getNumCoords(); std::cerr << "Tubes: #strips: " << nStrips << ", #corners: " << nPoints << std::endl; data->primitiveFlags = new unsigned int[nPoints]; data->spheres = new ispc::Sphere[nPoints]; const Tubes::CapStyle startStyle = tube->startStyle(), jointStyle = tube->jointStyle(), endStyle = tube->endStyle(); auto el = tube->components().data(); auto x = &tube->x()[0]; auto y = &tube->y()[0]; auto z = &tube->z()[0]; auto r = &tube->r()[0]; auto s = data->spheres; auto p = data->primitiveFlags; Index idx=0; for (Index strip=0; strip<nStrips; ++strip) { const Index begin = el[strip], end = el[strip+1]; vassert(idx == begin); for (Index i=begin; i<end; ++i) { s[idx].p.x = x[i]; s[idx].p.y = y[i]; s[idx].p.z = z[i]; s[idx].r = r[i]; p[idx] = ispc::PFNone; if (i == begin) { switch(startStyle) { case Tubes::Flat: p[idx] |= ispc::PFStartDisc; break; case Tubes::Round: p[idx] |= ispc::PFStartSphere; break; default: break; } } else if (i+1 != end) { if (jointStyle == Tubes::Flat) { p[idx] |= ispc::PFStartDisc; } } if (i+1 != end) { p[idx] |= ispc::PFCone; switch((i+2==end) ? endStyle : jointStyle) { case Tubes::Open: break; case Tubes::Flat: p[idx] |= ispc::PFEndDisc; break; case Tubes::Round: p[idx] |= i+2==end ? ispc::PFEndSphere : ispc::PFEndSphereSect; break; case Tubes::Arrow: p[idx] |= ispc::PFArrow; break; } } ++idx; } vassert(idx == end); } vassert(idx == nPoints); geom = newTubes(data.get(), nPoints > 0 ? nPoints-1 : 0); } if (geom) { if (this->normals && useNormals) { if (this->normals->guessMapping(geometry) == DataBase::Element) data->normalsPerPrimitiveMapping = 1; for (int c=0; c<3; ++c) { data->normals[c] = &this->normals->x(c)[0]; } } data->geomID = rtcAttachGeometry(data->scene, geom); rtcReleaseGeometry(geom); rtcCommitGeometry(geom); } rtcCommitScene(data->scene); }
RayRenderObject::RayRenderObject(RTCDevice device, int senderId, const std::string &senderPort, Object::const_ptr container, Object::const_ptr geometry, Object::const_ptr normals, Object::const_ptr colors, Object::const_ptr texture) : vistle::RenderObject(senderId, senderPort, container, geometry, normals, colors, texture) , data(new ispc::RenderObjectData) { data->device = device; data->scene = nullptr; data->geomId = RTC_INVALID_GEOMETRY_ID; data->instId = RTC_INVALID_GEOMETRY_ID; data->spheres = nullptr; data->primitiveFlags = nullptr; data->indexBuffer = nullptr; data->texWidth = 0; data->texData = nullptr; data->texCoords = nullptr; data->lighted = 1; data->hasSolidColor = hasSolidColor; data->perPrimitiveMapping = 0; for (int c=0; c<4; ++c) { data->solidColor[c] = solidColor[c]; } if (this->texture) { if (this->texture->guessMapping(geometry) == DataBase::Element) data->perPrimitiveMapping = 1; data->texWidth = this->texture->getWidth(); data->texData = this->texture->pixels().data(); data->texCoords = &this->texture->coords()[0]; } if (geometry->isEmpty()) { return; } data->scene = rtcDeviceNewScene(data->device, RTC_SCENE_STATIC|sceneFlags, intersections); if (auto tri = Triangles::as(geometry)) { Index numElem = tri->getNumElements(); if (numElem == 0) { numElem = tri->getNumCoords() / 3; } data->geomId = rtcNewTriangleMesh(data->scene, RTC_GEOMETRY_STATIC, numElem, tri->getNumCoords()); std::cerr << "Tri: #tri: " << tri->getNumElements() << ", #coord: " << tri->getNumCoords() << std::endl; Vertex* vertices = (Vertex*) rtcMapBuffer(data->scene, data->geomId, RTC_VERTEX_BUFFER); for (Index i=0; i<tri->getNumCoords(); ++i) { vertices[i].x = tri->x()[i]; vertices[i].y = tri->y()[i]; vertices[i].z = tri->z()[i]; } rtcUnmapBuffer(data->scene, data->geomId, RTC_VERTEX_BUFFER); data->indexBuffer = new Triangle[numElem]; rtcSetBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER, data->indexBuffer, 0, sizeof(Triangle)); Triangle* triangles = (Triangle*) rtcMapBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER); if (tri->getNumElements() == 0) { for (Index i=0; i<numElem; ++i) { triangles[i].v0 = i*3; triangles[i].v1 = i*3+1; triangles[i].v2 = i*3+2; triangles[i].elem = i; } } else { for (Index i=0; i<numElem; ++i) { triangles[i].v0 = tri->cl()[i*3]; triangles[i].v1 = tri->cl()[i*3+1]; triangles[i].v2 = tri->cl()[i*3+2]; triangles[i].elem = i; } } rtcUnmapBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER); } else if (auto poly = Polygons::as(geometry)) { Index ntri = poly->getNumCorners()-2*poly->getNumElements(); vassert(ntri >= 0); data->geomId = rtcNewTriangleMesh(data->scene, RTC_GEOMETRY_STATIC, ntri, poly->getNumCoords()); //std::cerr << "Poly: #tri: " << poly->getNumCorners()-2*poly->getNumElements() << ", #coord: " << poly->getNumCoords() << std::endl; Vertex* vertices = (Vertex*) rtcMapBuffer(data->scene, data->geomId, RTC_VERTEX_BUFFER); for (Index i=0; i<poly->getNumCoords(); ++i) { vertices[i].x = poly->x()[i]; vertices[i].y = poly->y()[i]; vertices[i].z = poly->z()[i]; } rtcUnmapBuffer(data->scene, data->geomId, RTC_VERTEX_BUFFER); data->indexBuffer = new Triangle[ntri]; rtcSetBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER, data->indexBuffer, 0, sizeof(Triangle)); Triangle* triangles = (Triangle*) rtcMapBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER); Index t = 0; for (Index i=0; i<poly->getNumElements(); ++i) { const Index start = poly->el()[i]; const Index end = poly->el()[i+1]; const Index nvert = end-start; const Index last = end-1; for (Index v=0; v<nvert-2; ++v) { triangles[t].elem = i; const Index v2 = v/2; if (v%2) { triangles[t].v0 = poly->cl()[last-v2]; triangles[t].v1 = poly->cl()[start+v2+1]; triangles[t].v2 = poly->cl()[last-v2-1]; } else { triangles[t].v0 = poly->cl()[start+v2]; triangles[t].v1 = poly->cl()[start+v2+1]; triangles[t].v2 = poly->cl()[last-v2]; } ++t; } } vassert(t == ntri); rtcUnmapBuffer(data->scene, data->geomId, RTC_INDEX_BUFFER); } else if (auto sph = Spheres::as(geometry)) { Index nsph = sph->getNumSpheres(); //std::cerr << "Spheres: #sph: " << nsph << std::endl; data->spheres = new ispc::Sphere[nsph]; auto x = &sph->x()[0]; auto y = &sph->y()[0]; auto z = &sph->z()[0]; auto r = &sph->r()[0]; auto s = data->spheres; for (Index i=0; i<nsph; ++i) { s[i].p.x = x[i]; s[i].p.y = y[i]; s[i].p.z = z[i]; s[i].r = r[i]; } data->geomId = registerSpheres((ispc::__RTCScene *)data->scene, data.get(), nsph); } else if (auto point = Points::as(geometry)) { Index np = point->getNumPoints(); //std::cerr << "Points: #sph: " << np << std::endl; data->spheres = new ispc::Sphere[np]; auto x = &point->x()[0]; auto y = &point->y()[0]; auto z = &point->z()[0]; auto s = data->spheres; for (Index i=0; i<np; ++i) { s[i].p.x = x[i]; s[i].p.y = y[i]; s[i].p.z = z[i]; s[i].r = pointSize; } data->lighted = 0; data->geomId = registerSpheres((ispc::__RTCScene *)data->scene, data.get(), np); } else if (auto line = Lines::as(geometry)) { Index nStrips = line->getNumElements(); Index nPoints = line->getNumCorners(); std::cerr << "Lines: #strips: " << nStrips << ", #corners: " << nPoints << std::endl; data->primitiveFlags = new unsigned int[nPoints]; data->spheres = new ispc::Sphere[nPoints]; auto el = &line->el()[0]; auto cl = &line->cl()[0]; auto x = &line->x()[0]; auto y = &line->y()[0]; auto z = &line->z()[0]; auto s = data->spheres; auto p = data->primitiveFlags; Index idx=0; for (Index strip=0; strip<nStrips; ++strip) { const Index begin = el[strip], end = el[strip+1]; for (Index c=begin; c<end; ++c) { Index i = cl[c]; s[idx].p.x = x[i]; s[idx].p.y = y[i]; s[idx].p.z = z[i]; s[idx].r = pointSize; p[idx] = ispc::PFNone; if (c+1 != end) p[idx] |= ispc::PFCone; p[idx] |= ispc::PFStartSphere; ++idx; } } vassert(idx == nPoints); data->lighted = 0; data->geomId = registerTubes((ispc::__RTCScene *)data->scene, data.get(), nPoints-1); } else if (auto tube = Tubes::as(geometry)) { Index nStrips = tube->getNumTubes(); Index nPoints = tube->getNumCoords(); std::cerr << "Tubes: #strips: " << nStrips << ", #corners: " << nPoints << std::endl; data->primitiveFlags = new unsigned int[nPoints]; data->spheres = new ispc::Sphere[nPoints]; const Tubes::CapStyle startStyle = tube->startStyle(), jointStyle = tube->jointStyle(), endStyle = tube->endStyle(); auto el = tube->components().data(); auto x = &tube->x()[0]; auto y = &tube->y()[0]; auto z = &tube->z()[0]; auto r = &tube->r()[0]; auto s = data->spheres; auto p = data->primitiveFlags; Index idx=0; for (Index strip=0; strip<nStrips; ++strip) { const Index begin = el[strip], end = el[strip+1]; vassert(idx == begin); for (Index i=begin; i<end; ++i) { s[idx].p.x = x[i]; s[idx].p.y = y[i]; s[idx].p.z = z[i]; s[idx].r = r[i]; p[idx] = ispc::PFNone; if (i == begin) { switch(startStyle) { case Tubes::Flat: p[idx] |= ispc::PFStartDisc; break; case Tubes::Round: p[idx] |= ispc::PFStartSphere; break; default: break; } } else if (i+1 != end) { if (jointStyle == Tubes::Flat) { p[idx] |= ispc::PFStartDisc; } } if (i+1 != end) { p[idx] |= ispc::PFCone; switch((i+2==end) ? endStyle : jointStyle) { case Tubes::Open: break; case Tubes::Flat: p[idx] |= ispc::PFEndDisc; break; case Tubes::Round: p[idx] |= i+2==end ? ispc::PFEndSphere : ispc::PFEndSphereSect; break; case Tubes::Arrow: p[idx] |= ispc::PFArrow; break; } } ++idx; } vassert(idx == end); } vassert(idx == nPoints); data->geomId = registerTubes((ispc::__RTCScene *)data->scene, data.get(), nPoints > 0 ? nPoints-1 : 0); } rtcCommit(data->scene); }