Object::ptr CutGeometry::cutGeometry(Object::const_ptr object) const { auto coords = Coords::as(object); if (!coords) return Object::ptr(); IsoDataFunctor decider = isocontrol.newFunc(object->getTransform(), &coords->x()[0], &coords->y()[0], &coords->z()[0]); switch (object->getType()) { case Object::TRIANGLES: { PlaneClip cutter(Triangles::as(object), decider); cutter.process(); return cutter.result(); } case Object::POLYGONS: { PlaneClip cutter(Polygons::as(object), decider); cutter.process(); return cutter.result(); } default: break; } return Object::ptr(); }
void PlaceHolder::setReal(Object::const_ptr r) { if (Object::const_ptr old = real()) old->unref(); d()->real = r->d(); if (r) r->ref(); }
shm_handle_t Shm::getHandleFromObject(Object::const_ptr object) const { #ifdef NO_SHMEM return object->d(); #else try { return m_shm->get_handle_from_address(object->d()); } catch (interprocess_exception &) { } return 0; #endif }
bool Object::Data::addAttachment(const std::string &key, Object::const_ptr obj) { boost::interprocess::scoped_lock<boost::interprocess::interprocess_recursive_mutex> lock(attachment_mutex); const Key skey(key.c_str(), Shm::the().allocator()); AttachmentMap::iterator it = attachments->find(skey); if (it != attachments->end()) { return false; } obj->ref(); attachments->insert(AttachmentMapValueType(skey, obj->d())); return true; }
bool Object::Data::addAttachment(const std::string &key, Object::const_ptr obj) { attachment_mutex_lock_type lock(attachment_mutex); const Key skey(key.c_str(), Shm::the().allocator()); AttachmentMap::const_iterator it = attachments.find(skey); if (it != attachments.end()) { return false; } obj->ref(); attachments.insert(AttachmentMapValueType(skey, obj->d())); return true; }
bool ColorAttribute::compute() { //std::cerr << "ColorAttribute: compute: execcount=" << m_executionCount << std::endl; auto color = p_color->getValue(); Object::const_ptr obj = expect<Object>("data_in"); if (!obj) return false; Object::ptr out = obj->clone(); out->addAttribute("_color", color); addObject("data_out", out); return true; }
Object::const_ptr Shm::getObjectFromHandle(const shm_handle_t & handle) const { Object::const_ptr ret; lockObjects(); Object::Data *od = getObjectDataFromHandle(handle); if (od) { od->ref(); unlockObjects(); ret.reset(Object::create(od)); od->unref(); } else { unlockObjects(); } return ret; }
bool AttachObject::compute() { //std::cerr << "AttachObject: compute: execcount=" << m_executionCount << std::endl; Object::const_ptr obj = expect<Object>("data_in"); if (!obj) return false; Object::ptr out = std::const_pointer_cast<Object>(obj); Object::ptr att(new Points(4)); obj->addAttachment("test", att); addObject("data_out", out); return true; }
void Object::copyAttributes(Object::const_ptr src, bool replace) { if (replace) { auto &m = d()->meta; auto &sm = src->meta(); m.setBlock(sm.block()); m.setNumBlocks(sm.numBlocks()); m.setTimeStep(sm.timeStep()); m.setNumTimesteps(sm.numTimesteps()); m.setRealTime(sm.realTime()); m.setAnimationStep(sm.animationStep()); m.setNumAnimationSteps(sm.numAnimationSteps()); m.setIteration(sm.iteration()); } d()->copyAttributes(src->d(), replace); }
bool AddAttribute::compute() { Object::const_ptr obj = expect<Object>("data_in"); if (!obj) return true; Object::ptr out = obj->clone(); for (int i=0; i<NumAttributes; ++i) { if (!p_name[i]->getValue().empty()) { out->addAttribute(p_name[i]->getValue(), p_value[i]->getValue()); } } addObject("data_out", out); return true; }
bool ObjectStatistics::compute() { //std::cerr << "ObjectStatistics: compute: execcount=" << m_executionCount << std::endl; Object::const_ptr obj = expect<Object>("data_in"); if (!obj) return true; if (obj->getTimestep()+1 > m_timesteps) m_timesteps = obj->getTimestep()+1; stats s; if (auto i = Indexed::as(obj)) { s.elements = i->getNumElements(); s.vertices = i->getNumCorners(); } else if (auto t = Triangles::as(obj)) { s.elements = t->getNumElements(); s.vertices = t->getNumCorners(); } if (auto c = Coords::as(obj)) { s.coords = c->getNumCoords(); if (c->normals()) ++s.normals; } else if (auto d = DataBase::as(obj)) { if (d->grid()) ++s.grids; if(auto v = Vec<Scalar, 3>::as(obj)) { s.data[3] = v->getSize(); } else if(auto v = Vec<Scalar, 1>::as(obj)) { s.data[1] = v->getSize(); } } s.blocks = 1; m_cur += s; return true; }
bool FilterNode::compute() { Object::const_ptr data = expect<Object>("data_in"); if (!data) return true; const bool invert = m_invertParam->getValue(); const Integer select = m_nodeParam->getValue(); bool pass = true; switch (m_criterionParam->getValue()) { case Rank: pass = select == rank(); break; case BlockNumber: pass = select == data->getBlock(); break; case Timestep: pass = select == data->getTimestep(); break; } if (invert) pass = !pass; if (pass) { passThroughObject("data_out", data); } else { Object::ptr obj = data->cloneType(); obj->setMeta(data->meta()); obj->copyAttributes(data); addObject("data_out", obj); } return true; }
bool WriteVistle::compute() { int count = 0; bool trunc = false; bool end = false; std::string format; Object::const_ptr obj = expect<Object>("grid_in"); if (!obj) return false; std::ios_base::openmode flags = std::ios::out; if (obj->hasAttribute("_mark_begin")) { close(); trunc = true; flags |= std::ios::trunc; } else { flags |= std::ios::app; } if (obj->hasAttribute("_mark_end")) { end = true; } switch(getIntParameter("format")) { default: case 0: flags |= std::ios::binary; format = "binary"; break; case 1: format = "text"; break; case 2: format = "xml"; break; } if (!m_ofs) { m_ofs = new std::ofstream(getStringParameter("filename").c_str(), flags); } if (trunc) *m_ofs << "vistle " << format << " 1 start" << std::endl; switch(getIntParameter("format")) { default: case 0: { if (!m_binAr) m_binAr = new ba::binary_oarchive(*m_ofs); obj->save(*m_binAr); break; } case 1: { if (!m_textAr) m_textAr = new ba::text_oarchive(*m_ofs); obj->save(*m_textAr); break; } case 2: { if (!m_xmlAr) m_xmlAr = new ba::xml_oarchive(*m_ofs); obj->save(*m_xmlAr); break; } } ++count; close(); //*m_ofs << std::endl << "vistle separator" << std::endl; if (trunc) { std::cerr << "saved"; } else { std::cerr << "appended"; } if (end) { std::cerr << " final"; close(); } std::cerr << " [" << count << "] to " << getStringParameter("filename") << " (" << format << ")" << std::endl; return true; }
void Object::copyAttachments(Object::const_ptr src, bool replace) { d()->copyAttachments(src->d(), replace); }
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); }