diff --git a/modules/gfx/pymod/export_entity.cc b/modules/gfx/pymod/export_entity.cc index 23e341b04754d0d960e78747277459dba023d54c..8d80170fb5ad45da30da851cc7a816a292b00c77 100644 --- a/modules/gfx/pymod/export_entity.cc +++ b/modules/gfx/pymod/export_entity.cc @@ -92,6 +92,16 @@ void color_by_08(Entity* e, e->ColorBy(prop,c1,c2); } +// temporary, see comment in gfx/entity.hh +void detail_color_by_02(Entity* e, + const String& prop, + const Gradient& gradient, + float minv,float maxv) +{ + e->DetailColorBy(prop,gradient,minv,maxv); +} + + void radius_by_01(Entity* e, const String& prop, float rmin,float rmax, @@ -245,6 +255,7 @@ void export_Entity() .add_property("selection", &Entity::GetSelection, &Entity::SetSelection) .def("GetView", &Entity::GetView) + .def("UpdateView", &Entity::UpdateView) .def("GetRenderModeName", &Entity::GetRenderModeName) .def("GetNotEmptyRenderModes", &Entity::GetNotEmptyRenderModes) .def("SetRenderMode", set_rm1, arg("keep")=false) @@ -261,6 +272,7 @@ void export_Entity() .def("ColorBy", color_by_06) .def("ColorBy", color_by_07) .def("ColorBy", color_by_08) + .def("DetailColorBy", detail_color_by_02) COLOR_BY_DEF() .def("RadiusBy", radius_by_01) .def("RadiusBy", radius_by_02) diff --git a/modules/gfx/src/entity.cc b/modules/gfx/src/entity.cc index d6dad69872bb450e5dd41ca4cb448eb162265a58..dfae13a3707eddb51e9a12dc4516c668d1d70e44 100644 --- a/modules/gfx/src/entity.cc +++ b/modules/gfx/src/entity.cc @@ -105,8 +105,9 @@ Entity::Entity(const String& name, impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm) { - if (renderer_.find(rm)!=renderer_.end()) { - return renderer_.find(rm)->second; + RendererMap::iterator rit = renderer_.find(rm); + if(rit!=renderer_.end()) { + return rit->second; } impl::EntityRenderer* r=NULL; switch (rm) { @@ -117,22 +118,22 @@ impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm) r=new impl::CustomRenderer(); break; case RenderMode::SLINE: - r=new impl::SlineRenderer(trace_); + r=new impl::SlineRenderer(&trace_); break; case RenderMode::LINE_TRACE: - r=new impl::LineTraceRenderer(trace_); + r=new impl::LineTraceRenderer(&trace_); break; case RenderMode::TRACE: - r=new impl::TraceRenderer(trace_); + r=new impl::TraceRenderer(&trace_); break; case RenderMode::HSC: - r=new impl::CartoonRenderer(trace_); + r=new impl::CartoonRenderer(&trace_,false); break; case RenderMode::CPK: r=new impl::CPKRenderer(); break; case RenderMode::TUBE: - r=new impl::CartoonRenderer(trace_, true); + r=new impl::CartoonRenderer(&trace_, true); break; default: return 0; @@ -148,7 +149,7 @@ void Entity::init(RenderMode::Type rm) update_view_=true; render_mode_=rm; - trace_.SetView(this->GetView()); + trace_.ResetView(this->GetView()); sel_=this->GetView().CreateEmptyView(); impl::EntityRenderer* r=this->GetOrCreateRenderer(rm); if(!r) return; @@ -197,6 +198,18 @@ void Entity::SetBlurFactors(float bf1,float bf2) void Entity::Rebuild() { geom::Vec3 delta=GetTF().GetTrans()-GetTF().GetCenter(); + + if(update_view_) { + EntityView nv=this->GetView(); + for (RendererMap::iterator i=renderer_.begin(), + e=renderer_.end(); i!=e; ++i) { + i->second->ClearViews(); + i->second->AddView(nv); + i->second->UpdateViews(); + i->second->PrepareRendering(); + } + } + this->ReapplyColorOps(); FlagRebuild(); geom::Vec3 center=this->GetCenter(); @@ -764,6 +777,16 @@ void Entity::ColorBy(const String& prop, this->Apply(glop); } +void Entity::DetailColorBy(const String& prop, + const Gradient& gradient, + float minv,float maxv, + mol::Prop::Level level) +{ + GradientLevelColorOp glop = GradientLevelColorOp("",prop, gradient,minv,maxv,level); + glop.SetMask(DETAIL_COLOR); + this->Apply(glop); +} + void Entity::ColorBy(const String& prop, const Color& c1, const Color& c2, float minv, float maxv, @@ -947,4 +970,11 @@ void Entity::ReapplyColorOps() GfxObj::ReapplyColorOps(); } +void Entity::UpdateView() +{ + update_view_=true; + Rebuild(); + UpdatePositions(); +} + }} // ns diff --git a/modules/gfx/src/entity.hh b/modules/gfx/src/entity.hh index 368445df056732e6ad47777a1a36fea0b72deea8..c0b3c3a9fd48f94bfbfe67e76530f5f5c36f4c06 100644 --- a/modules/gfx/src/entity.hh +++ b/modules/gfx/src/entity.hh @@ -199,6 +199,12 @@ public: float minv,float maxv, mol::Prop::Level hint=mol::Prop::UNSPECIFIED); + // temporary, should be incorporated with ColorBy + void DetailColorBy(const String& prop, + const Gradient& gradient, + float minv,float maxv, + mol::Prop::Level hint=mol::Prop::UNSPECIFIED); + // convenience void ColorBy(const String& prop, const Gradient& gradient, @@ -257,6 +263,9 @@ public: void ApplyOptions(RenderMode::Type render_mode, RenderOptionsPtr& render_options); bool HasSelection() const; + + void UpdateView(); + protected: virtual void CustomPreRenderGL(bool flag); diff --git a/modules/gfx/src/gfx_object.cc b/modules/gfx/src/gfx_object.cc index 319692f50080fcac899901ef7ef4b8d554b1ef7f..3959e465325c5987d36b04b064c710e2c364ac5b 100644 --- a/modules/gfx/src/gfx_object.cc +++ b/modules/gfx/src/gfx_object.cc @@ -448,6 +448,9 @@ void GfxObj::RenderPov(PovState& pov) pov.start_obj(GetName(),1.0,1.0,1.0); // apply local transformation // using transform_ + if(rebuild_ || refresh_) { + PreRenderGL(true); + } CustomRenderPov(pov); pov.end_obj(); } diff --git a/modules/gfx/src/impl/backbone_trace.cc b/modules/gfx/src/impl/backbone_trace.cc index d4314bea8901f49678e55af9fa2cff6f791bfe1d..fb4b714cc363bc243f8a77d096d10765e18fcd93 100644 --- a/modules/gfx/src/impl/backbone_trace.cc +++ b/modules/gfx/src/impl/backbone_trace.cc @@ -39,7 +39,7 @@ public: { if(last_chain_ && chain!=last_chain_) { if(!list_.empty()) { - backbone_trace_->AddNodeList(list_); + backbone_trace_->AddNodeEntryList(list_); list_.clear(); } last_chain_=chain; @@ -51,7 +51,7 @@ public: { if(!mol::InSequence(last_residue_,res)) { if(!list_.empty()) { - backbone_trace_->AddNodeList(list_); + backbone_trace_->AddNodeEntryList(list_); list_.clear(); } } @@ -76,7 +76,7 @@ public: virtual void OnExit() { if (!list_.empty()) { - backbone_trace_->AddNodeList(list_); + backbone_trace_->AddNodeEntryList(list_); list_.clear(); } } @@ -87,23 +87,38 @@ private: NodeEntryList list_; }; +BackboneTrace::BackboneTrace() +{} + BackboneTrace::BackboneTrace(const mol::EntityView& ent) { view_=ent; - TraceBuilder trace(this); - if (view_) { - view_.Apply(trace); - } + Rebuild(); } -BackboneTrace::BackboneTrace() +void BackboneTrace::ResetView(const mol::EntityView& ent) { - + view_=ent; + Rebuild(); } -void BackboneTrace::SetView(const mol::EntityView& ent) +int BackboneTrace::GetListCount() const +{ + return node_list_list_.size(); +} + +const NodeEntryList& BackboneTrace::GetList(int index) const +{ + return node_list_list_[index]; +} + +NodeEntryList& BackboneTrace::GetList(int index) +{ + return node_list_list_[index]; +} + +void BackboneTrace::Rebuild() { - view_=ent; if (view_) { node_list_list_.clear(); TraceBuilder trace(this); @@ -111,7 +126,7 @@ void BackboneTrace::SetView(const mol::EntityView& ent) } } -void BackboneTrace::AddNodeList(const NodeEntryList& l) +void BackboneTrace::AddNodeEntryList(const NodeEntryList& l) { if(l.size()>=3) { node_list_list_.push_back(l); @@ -183,114 +198,25 @@ void BackboneTrace::PrepList(NodeEntryList& nelist) nelist[i+1].normal=nelist[i].normal; } -int BackboneTrace::GetListCount() const +BackboneTrace BackboneTrace::CreateSubset(const mol::EntityView& subview) { - return node_list_list_.size(); -} - -const NodeEntryList& BackboneTrace::GetList(int index) const -{ - return node_list_list_[index]; -} - -NodeEntryList& BackboneTrace::GetList(int index) -{ - return node_list_list_[index]; -} - -void BackboneTrace::Rebuild() -{ - TraceBuilder trace(this); - view_.Apply(trace); -} - -NodeListSubset::NodeListSubset(BackboneTrace& trace, int index): - trace_(trace), list_index_(index), at_start_(0), at_end_(0) -{ -} - -TraceSubset::TraceSubset(BackboneTrace& trace, - const mol::EntityView& view, int n): - trace_(trace), overshoot_(n) -{ - this->Update(view); -} - -TraceSubset::TraceSubset(BackboneTrace& trace, int n): - trace_(trace), overshoot_(n) -{ - -} - - -void TraceSubset::NodeListEnd(NodeListSubset& nl, int c, int s) -{ - if (nl.GetSize()>0) { - int n=std::min(s-(nl.indices_.back()+1), overshoot_); - nl.at_end_=n; - while (n>0) { - nl.indices_.push_back(nl.indices_.back()+1); - --n; - } - } -} - -void TraceSubset::NodeListStart(NodeListSubset& nl, int c) -{ - if (nl.GetSize()==0 && c>0) { - for (int i=std::max(0,c-overshoot_); i<c; ++i) { - nl.indices_.push_back(i); - } - nl.at_start_=nl.indices_.size(); - } -} - - -void TraceSubset::Update(const mol::EntityView& view) -{ - - lists_.clear(); - if (!view.IsValid()) { - return; - } - for (int i=0; i<trace_.GetListCount(); ++i) { - const NodeEntryList& l=trace_.GetList(i); - int c=0; - NodeEntryList::const_iterator j=l.begin(),e=l.end(); - NodeListSubset curr(trace_, i); - while (j!=e) { - while (j!=e && view.FindAtom(j->atom)) { - if (curr.indices_.empty()) { - this->NodeListStart(curr, c); - } - curr.indices_.push_back(c); - ++j; ++c; - } - if (curr.GetSize()) { - this->NodeListEnd(curr, curr.indices_.back(), l.size()); - lists_.push_back(curr); - curr=NodeListSubset(trace_, i); - } else { - ++c; ++j; + BackboneTrace nrvo; + nrvo.view_=subview; + nrvo.node_list_list_.clear(); + for(NodeEntryListList::const_iterator nitnit=node_list_list_.begin();nitnit!=node_list_list_.end();++nitnit) { + NodeEntryList new_nlist; + const NodeEntryList& nlist=*nitnit; + for(NodeEntryList::const_iterator nit=nlist.begin();nit!=nlist.end();++nit) { + if(subview.FindAtom(nit->atom).IsValid()) { + new_nlist.push_back(*nit); } } + if(!new_nlist.empty()) { + nrvo.node_list_list_.push_back(new_nlist); + } } + return nrvo; } -NodeListSubset& NodeListSubset::operator=(const NodeListSubset& rhs) -{ - trace_=rhs.trace_; - list_index_=rhs.list_index_; - indices_=rhs.indices_; - return *this; -} - -TraceSubset& TraceSubset::operator=(const TraceSubset& rhs) -{ - trace_=rhs.trace_; - lists_=rhs.lists_; - overshoot_=rhs.overshoot_; - return *this; -} +}}} // ns -}}} diff --git a/modules/gfx/src/impl/backbone_trace.hh b/modules/gfx/src/impl/backbone_trace.hh index 25ebdce1fe5cf3b764c0aac06e64b546121f4434..debcc54b59b653e5370f3dbe581d46fd3fac87b6 100644 --- a/modules/gfx/src/impl/backbone_trace.hh +++ b/modules/gfx/src/impl/backbone_trace.hh @@ -40,100 +40,41 @@ class BackboneTraceBuilder; class DLLEXPORT_OST_GFX BackboneTrace { public: - BackboneTrace(const mol::EntityView& ent); + // empty trace BackboneTrace(); - + + // initialize with a view, and build + BackboneTrace(const mol::EntityView& ent); + + // number of node-lists int GetListCount() const; - + + // grab a list const NodeEntryList& GetList(int index) const; + // grab a list NodeEntryList& GetList(int index); - - void SetView(const mol::EntityView& ent); - - void AddNodeList(const NodeEntryList& entries); - static void PrepList(NodeEntryList& nelist); + // reset the view and rebuild + void ResetView(const mol::EntityView& ent); + + // used internally - adds a finished nodelist + void AddNodeEntryList(const NodeEntryList& entries); + // used internally - calculates some derived values for a nodelist + static void PrepList(NodeEntryList& nelist); + + // re-creates internal nodelist-list based on view void Rebuild(); + // extract portions of this backbone trace for a subview + // this is faster then re-generating a trace + BackboneTrace CreateSubset(const mol::EntityView& subview); + private: mol::EntityView view_; NodeEntryListList node_list_list_; }; -/// \internal -/// \brief a subset of a node list -class DLLEXPORT_OST_GFX NodeListSubset { -public: - friend class TraceSubset; - - NodeListSubset(BackboneTrace& trace, int index); - - int GetSize() const - { - return indices_.size(); - } - int AtStart() const - { - return at_start_; - } - - int AtEnd() const - { - return at_end_; - } - const NodeEntry& operator [](int index) const - { - assert(index>=0 && index<static_cast<int>(indices_.size())); - return trace_.GetList(list_index_)[indices_[index]]; - } - NodeEntry& operator [](int index) - { - assert(index>=0 && index<static_cast<int>(indices_.size())); - return trace_.GetList(list_index_)[indices_[index]]; - } - NodeListSubset& operator=(const NodeListSubset& rhs); -private: - BackboneTrace& trace_; - int list_index_; -protected: - std::vector<int> indices_; - int at_start_; - int at_end_; -}; - -/// \brief a subset of the trace -class DLLEXPORT_OST_GFX TraceSubset { -public: - TraceSubset(BackboneTrace& trace, const mol::EntityView& view, int n); - TraceSubset(BackboneTrace& trace, int n); - - const NodeListSubset& operator[](int index) const - { - return lists_[index]; - } - - NodeListSubset& operator[](int index) - { - return lists_[index]; - } - - int GetSize() const - { - return lists_.size(); - } - void SetOvershoot(int n) { overshoot_=n; } - int GetOvershoot() const { return overshoot_; } - TraceSubset& operator=(const TraceSubset& rhs); - void Update(const mol::EntityView& view); -private: - void NodeListStart(NodeListSubset& nl, int c); - void NodeListEnd(NodeListSubset& nl, int c, int s); - BackboneTrace& trace_; - std::vector<NodeListSubset> lists_; - int overshoot_; -}; - }}} #endif diff --git a/modules/gfx/src/impl/cartoon_renderer.cc b/modules/gfx/src/impl/cartoon_renderer.cc index c17c1efd861af4db7f0816f933d0177b4a03c191..f4a52b7ee9672ebdf289b8adfc533e15e4edffdf 100644 --- a/modules/gfx/src/impl/cartoon_renderer.cc +++ b/modules/gfx/src/impl/cartoon_renderer.cc @@ -16,6 +16,11 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +/* + Author: Ansgar Philippsen +*/ + #include "cartoon_renderer.hh" #include <Eigen/Core> @@ -34,7 +39,7 @@ static const unsigned int MAX_ARC_DETAIL=12; using namespace impl; -CartoonRenderer::CartoonRenderer(BackboneTrace& trace, bool force_tube): +CartoonRenderer::CartoonRenderer(BackboneTrace* trace, bool force_tube): TraceRendererBase(trace, 3), force_tube_(force_tube), options_(new CartoonRenderOptions(force_tube)) { @@ -46,7 +51,7 @@ void CartoonRenderer::SetForceTube(bool force_tube) force_tube_ = force_tube; } -void CartoonRenderer::PrepareRendering(const TraceSubset& subset, +void CartoonRenderer::PrepareRendering(const BackboneTrace& subset, IndexedVertexArray& va, SplineEntryListList& spline_list_list, bool is_sel) @@ -61,11 +66,11 @@ void CartoonRenderer::PrepareRendering(const TraceSubset& subset, va.SetColorMaterial(true); va.SetMode(0x4); va.SetPolyMode(options_->GetPolyMode()); - for (int node_list=0; node_list<subset.GetSize(); ++node_list) { + for (int node_list=0; node_list<subset.GetListCount(); ++node_list) { // first build the spline SplineEntryList spl; - const NodeListSubset& nl=subset[node_list]; - for (int i=0; i<nl.GetSize();++i) { + const NodeEntryList& nl=subset.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { int type=0; const NodeEntry& entry=nl[i]; if(!force_tube_) { @@ -112,8 +117,6 @@ void CartoonRenderer::PrepareRendering() state_=0; } -void CartoonRenderer::Render(){} - bool CartoonRenderer::CanSetOptions(RenderOptionsPtr& render_options) { return render_options.get()->GetRenderMode()==RenderMode::HSC; @@ -302,7 +305,6 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va, unsigned int detail = std::min(MAX_ARC_DETAIL, std::max(options_->GetArcDetail(), (unsigned int)1)); - int spline_detail=std::max((unsigned int) 1, options_->GetSplineDetail()); std::vector<TraceProfile> profiles; float factor=is_sel ? 0.2 : 0.0; profiles.push_back(GetCircProfile(detail, @@ -346,15 +348,13 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va, */ SplineEntryList slist=*it; if(slist.empty()) continue; - int sit=0, send=slist.size()-spline_detail+1; - //int sit=0,send=slist.size(); - TraceProfile tprof1=TransformAndAddProfile(profiles,slist[sit],va); - CapProfile(tprof1,slist[sit],true,va); + TraceProfile tprof1=TransformAndAddProfile(profiles,slist[0],va); + CapProfile(tprof1,slist[0],true,va); TraceProfile tprof2; - SplineEntry last_se=slist[std::max(0,send-1)]; - for (int sc=sit+1; sc<send; ++sc) { - if(slist[sc].type==3) { - if(slist[sc-1].type==2) { + unsigned int sc=1; + for (; sc<slist.size(); ++sc) { + if(slist.at(sc).type==3) { + if(slist.at(sc-1).type==2) { // boundary to arrow SplineEntry se(slist[sc]); tprof2=TransformAndAddProfile(profiles,se, va); @@ -365,7 +365,7 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va, se.type2=4; tprof2=TransformAndAddProfile(profiles,se, va); } else { - SplineEntry se(slist[sc]); + SplineEntry se(slist.at(sc)); se.type1=4; if(options_->GetStrandMode()==1) se.type2=5; tprof2=TransformAndAddProfile(profiles,se, va); @@ -375,14 +375,11 @@ void CartoonRenderer::RebuildSplineObj(IndexedVertexArray& va, } AssembleProfile(tprof1,tprof2,va); tprof1=tprof2; - last_se=slist[sc]; } - CapProfile(tprof1,slist.at(send-1),false,va); + CapProfile(tprof1,slist.at(sc-1),false,va); } } - - TraceProfile CartoonRenderer::TransformAndAddProfile(const std::vector<TraceProfile>& profiles, const SplineEntry& se, IndexedVertexArray& va) { assert(se.type1>=0 && se.type1<=5); diff --git a/modules/gfx/src/impl/cartoon_renderer.hh b/modules/gfx/src/impl/cartoon_renderer.hh index 6b2b703f23b9fc34a590d7151df5da7dcba77f5c..d8a98f761a800deb13c8f36f893f9b8029e65deb 100644 --- a/modules/gfx/src/impl/cartoon_renderer.hh +++ b/modules/gfx/src/impl/cartoon_renderer.hh @@ -16,6 +16,11 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +/* + Author: Ansgar Philippsen +*/ + #ifndef OST_GFX_CARTOON_RENDERER_HH #define OST_GFX_CARTOON_RENDERER_HH @@ -34,23 +39,19 @@ namespace ost { namespace gfx { namespace impl { /// \internal class DLLEXPORT_OST_GFX CartoonRenderer: public TraceRendererBase { public: - CartoonRenderer(BackboneTrace& trace, bool force_tube=false); + CartoonRenderer(BackboneTrace* trace, bool force_tube=false); + virtual ~CartoonRenderer(); virtual void PrepareRendering(); - virtual void Render(); virtual bool CanSetOptions(RenderOptionsPtr& render_options); virtual void SetOptions(RenderOptionsPtr& render_options); virtual RenderOptionsPtr GetOptions(); - virtual void SetForceTube(bool force_tube); - - - virtual ~CartoonRenderer(); private: - void PrepareRendering(const TraceSubset& subset, IndexedVertexArray& va, + void PrepareRendering(const BackboneTrace& subset, IndexedVertexArray& va, SplineEntryListList& spline_list_list, bool is_sel); void FudgeSplineObj(IndexedVertexArray&, SplineEntryListList&); diff --git a/modules/gfx/src/impl/cpk_renderer.cc b/modules/gfx/src/impl/cpk_renderer.cc index 981ff47f38f1fe93db65a8bc64b04b7f5bc1b3cb..fc3b2b916170cc0e5dc16e2ea9f3a0b425fb6cdb 100644 --- a/modules/gfx/src/impl/cpk_renderer.cc +++ b/modules/gfx/src/impl/cpk_renderer.cc @@ -70,21 +70,18 @@ void CPKRenderer::PrepareRendering(GfxView& view, IndexedVertexArray& va, bool i state_=0; } -void CPKRenderer::Render() +void CPKRenderer::Render(RenderPass pass) { if(options_!=NULL){ #if OST_SHADER_SUPPORT_ENABLED if(options_->GetCPKMode()==1 || options_->GetCPKMode()==2) { this->RenderCPK2(); return; - } else { - this->RenderCPK3(); - return; } -#else - this->RenderCPK3();; #endif } + // fall back to parent if above did not fire + EntityRenderer::Render(pass); } void CPKRenderer::RenderPov(PovState& pov, const std::string& name) diff --git a/modules/gfx/src/impl/cpk_renderer.hh b/modules/gfx/src/impl/cpk_renderer.hh index b44a82e41dfaa5992727c348145c9ff50b8e8cb3..81372f2d022127c94df0dfff1cd189cc5ae4a3c4 100644 --- a/modules/gfx/src/impl/cpk_renderer.hh +++ b/modules/gfx/src/impl/cpk_renderer.hh @@ -37,7 +37,7 @@ public: virtual void RenderPov(PovState& pov, const std::string& name); - virtual void Render(); + virtual void Render(RenderPass pass=STANDARD_RENDER_PASS); virtual bool CanSetOptions(RenderOptionsPtr& render_options); virtual void SetOptions(RenderOptionsPtr& render_options); diff --git a/modules/gfx/src/impl/debug_renderer.cc b/modules/gfx/src/impl/debug_renderer.cc index 27138b32ef6b4f1d88271b447168f0de58dc1896..c77dca5687203f39c4969ceb5625d641ec1fbef9 100644 --- a/modules/gfx/src/impl/debug_renderer.cc +++ b/modules/gfx/src/impl/debug_renderer.cc @@ -33,7 +33,7 @@ namespace gfx { using namespace impl; using namespace mol; -DebugRenderer::DebugRenderer(BackboneTrace& trace): +DebugRenderer::DebugRenderer(BackboneTrace* trace): TraceRendererBase(trace, 2), options_(new SlineRenderOptions()) { this->SetName("Debug"); } diff --git a/modules/gfx/src/impl/debug_renderer.hh b/modules/gfx/src/impl/debug_renderer.hh index 206f592ddb3b7bcc4006d2a620f0a41488525e26..3a2b6e79a464b780fbb13ef40a794743564f40a4 100644 --- a/modules/gfx/src/impl/debug_renderer.hh +++ b/modules/gfx/src/impl/debug_renderer.hh @@ -30,7 +30,7 @@ namespace ost { namespace gfx { namespace impl { class DLLEXPORT_OST_GFX DebugRenderer: public TraceRendererBase { public: - DebugRenderer(BackboneTrace& trace); + DebugRenderer(BackboneTrace* trace); virtual void PrepareRendering(); virtual void Render(); diff --git a/modules/gfx/src/impl/entity_detail.cc b/modules/gfx/src/impl/entity_detail.cc index 1d5a3c226c70b674bf9076388272bea46de76fd1..4d2857b4b746ab50d4f61c8cbe22c5fc11102ccb 100644 --- a/modules/gfx/src/impl/entity_detail.cc +++ b/modules/gfx/src/impl/entity_detail.cc @@ -95,16 +95,20 @@ static int bsplineGet(float *xa, float *ya, float *y2a, int n, float x, float *y #define SPLINE_ENTRY_INTERPOLATE(COMPONENT) \ for(int c=0;c<size;++c) { \ - yc[c]=entry_list[c]. COMPONENT ; \ + yc[c]=entry_list.at(c). COMPONENT ; \ } \ bsplineGen(xp,yp,size,1.0e30,1.0e30,y2p); \ - for(int c=0;c<size;++c) { \ + for(int c=0;c<size-1;++c) { \ for(int d=0;d<nsub;++d) { \ float u=static_cast<float>(c*nsub+d)*i_nsub; \ float v=0.0; \ bsplineGet(xp,yp,y2p,size,u,&v); \ - sublist[c*nsub+d]. COMPONENT = v; \ + sublist.at(c*nsub+d). COMPONENT = v; \ } \ + float u=static_cast<float>((size-1)*nsub)*i_nsub; \ + float v=0.0; \ + bsplineGet(xp,yp,y2p,size,u,&v); \ + sublist.at((size-1)*nsub). COMPONENT = v; \ } SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub) @@ -113,10 +117,11 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub) return entry_list; } int size=entry_list.size(); - if (size==0) { + if (size<2) { return entry_list; } - int ipsize=(size)*nsub; + // we want to go to the last point, but not beyond + int ipsize=(size-1)*nsub+1; float i_nsub=1.0/static_cast<float>(nsub); std::vector<float> xc(size); std::vector<float> yc(size); @@ -153,14 +158,14 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub) // assign direction and normal // entity trace has the same algorithm - geom::Vec3 p0 = sublist[0].position; - geom::Vec3 p1 = sublist[1].position; - geom::Vec3 p2 = sublist[2].position; + geom::Vec3 p0 = sublist.at(0).position; + geom::Vec3 p1 = sublist.at(1).position; + geom::Vec3 p2 = ipsize>2 ? sublist.at(2).position : p1+(p1-p0); // normal of 0 is set at the end - sublist[0].direction=geom::Normalize(p1-p0); - sublist[0].v1=geom::Normalize(sublist[0].v1); - geom::Vec3 orth = geom::Cross(sublist[0].direction,sublist[0].v1); - sublist[0].v0 = geom::Normalize(geom::Cross(orth,sublist[0].direction)); + sublist.at(0).direction=geom::Normalize(p1-p0); + sublist.at(0).v1=geom::Normalize(sublist.at(0).v1); + geom::Vec3 orth = geom::Cross(sublist.at(0).direction,sublist.at(0).v1); + sublist.at(0).v0 = geom::Normalize(geom::Cross(orth,sublist.at(0).direction)); // reference normal to avoid twisting //geom::Vec3 nref=geom::Normalize(geom::Cross(p0-p1,p2-p1)); @@ -170,90 +175,83 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub) geom::Vec3 p12 = p2-p1; // correction for perfectly aligned consecutive directions if(p10==-p12 || p10==p12) p12+=geom::Vec3(0.001,0.001,0.001); - sublist[i].normal=geom::Normalize(geom::Cross(p10,p12)); + sublist.at(i).normal=geom::Normalize(geom::Cross(p10,p12)); // paranoid error checking due to occasional roundoff troubles float cosw = geom::Dot(geom::Normalize(p10),geom::Normalize(p12)); cosw = std::min(float(1.0),std::max(float(-1.0),cosw)); float omega=0.5*acos(cosw); - orth=geom::AxisRotation(sublist[i].normal, -omega)*p12; - sublist[i].direction=geom::Normalize(geom::Cross(sublist[i].normal,orth)); + orth=geom::AxisRotation(sublist.at(i).normal, -omega)*p12; + sublist.at(i).direction=geom::Normalize(geom::Cross(sublist.at(i).normal,orth)); // twist avoidance - sublist[i].v1=geom::Normalize(sublist[i].v1); - orth = geom::Cross(sublist[i].direction,sublist[i].v1); - sublist[i].v0 = geom::Normalize(geom::Cross(orth,sublist[i].direction)); - if(geom::Dot(sublist[i-1].v0,sublist[i].v0)<0.0) { - sublist[i].v0=-sublist[i].v0; - //sublist[i].nflip = !sublist[i].nflip; + sublist.at(i).v1=geom::Normalize(sublist.at(i).v1); + orth = geom::Cross(sublist.at(i).direction,sublist.at(i).v1); + sublist.at(i).v0 = geom::Normalize(geom::Cross(orth,sublist.at(i).direction)); + if(geom::Dot(sublist.at(i-1).v0,sublist.at(i).v0)<0.0) { + sublist.at(i).v0=-sublist.at(i).v0; + //sublist.at(i).nflip = !sublist.at(i).nflip; } // avoid twisting - //if(geom::Dot(sublist[i].normal,nref)<0.0) sublist[i].normal=-sublist[i].normal; - //nref=sublist[i].normal; + //if(geom::Dot(sublist.at(i).normal,nref)<0.0) sublist.at(i).normal=-sublist.at(i).normal; + //nref=sublist.at(i).normal; // skip over shift for the last iteration if(i==sublist.size()-2) break; // shift to i+1 for next iteration - p0 = sublist[i].position; - p1 = sublist[i+1].position; - p2 = sublist[i+2].position; + p0 = sublist.at(i).position; + p1 = sublist.at(i+1).position; + p2 = sublist.at(i+2).position; } // assign remaining ones - sublist[0].normal=sublist[1].normal; - sublist[i+1].direction=geom::Normalize(p2-p1); - sublist[i+1].normal=sublist[i].normal; - sublist[i+1].v1=geom::Normalize(sublist[i+1].v1); - orth = geom::Cross(sublist[i+1].direction,sublist[i+1].v1); - sublist[i+1].v0 = geom::Normalize(geom::Cross(orth,sublist[i+1].direction)); + sublist.at(0).normal=sublist.at(1).normal; + sublist.at(i+1).direction=geom::Normalize(p2-p1); + sublist.at(i+1).normal=sublist.at(i).normal; + sublist.at(i+1).v1=geom::Normalize(sublist.at(i+1).v1); + orth = geom::Cross(sublist.at(i+1).direction,sublist.at(i+1).v1); + sublist.at(i+1).v0 = geom::Normalize(geom::Cross(orth,sublist.at(i+1).direction)); // hack // TODO: merge this with above routine for(unsigned int i=0;i<sublist.size()-1;++i) { - sublist[i].normal = sublist[i].v0; + sublist.at(i).normal = sublist.at(i).v0; } // finally the non-interpolated type // with some tweaks for proper strand rendering - for(int c=0;c<size;++c) { + for(int c=0;c<size-1;++c) { int type1=entry_list[c].type; int type2=entry_list[std::min(c+1,size-1)].type; -# if 0 - //int type0=entry_list[std::max(0,c-1)].type; - if(type1==2 && type2==3) { - type1=2; - type2=2; - } else if(type1==3) { - type1=4; - // uncommenting this causes the strand arrows - // to blend into a tip instead of the n+1 - // profile - gives visual artefacts - //type2=3; - } -#endif for(int d=0;d<nsub;++d) { - sublist[c*nsub+d].type=entry_list[c].type; - sublist[c*nsub+d].type1=type1; - sublist[c*nsub+d].type2=type2; - sublist[c*nsub+d].frac=float(d)/float(nsub); + sublist.at(c*nsub+d).type=entry_list[c].type; + sublist.at(c*nsub+d).type1=type1; + sublist.at(c*nsub+d).type2=type2; + sublist.at(c*nsub+d).frac=float(d)/float(nsub); } } + int type1=entry_list.back().type; + int type2=type1; + sublist.back().type=entry_list.back().type; + sublist.back().type1=type1; + sublist.back().type2=type2; + sublist.back().frac=0.0; // the nflip flags for helices for correct inside/outside assignment int c=0; bool nflip=false; - while(c<nsub*size-1) { + while(c<nsub*(size-1)) { int cstart=c; - if(sublist[c].type==1 && sublist[c+1].type==1) { - geom::Vec3 n = geom::Normalize(geom::Cross(sublist[c].normal, - sublist[c].direction)); - geom::Vec3 p0 = sublist[c].position+n; - geom::Vec3 q0 = sublist[c].position-n; + if(sublist.at(c).type==1 && sublist.at(c+1).type==1) { + geom::Vec3 n = geom::Normalize(geom::Cross(sublist.at(c).normal, + sublist.at(c).direction)); + geom::Vec3 p0 = sublist.at(c).position+n; + geom::Vec3 q0 = sublist.at(c).position-n; float psum=0.0; float qsum=0.0; ++c; - while(sublist[c].type==1 && c<nsub*size) { - n = geom::Normalize(geom::Cross(sublist[c].normal, - sublist[c].direction)); - geom::Vec3 p1 = sublist[c].position+n; - geom::Vec3 q1 = sublist[c].position-n; + while(sublist.at(c).type==1 && c<nsub*size) { + n = geom::Normalize(geom::Cross(sublist.at(c).normal, + sublist.at(c).direction)); + geom::Vec3 p1 = sublist.at(c).position+n; + geom::Vec3 q1 = sublist.at(c).position-n; psum+=Length(p1-p0); qsum+=Length(q1-q0); p0=p1; @@ -263,7 +261,7 @@ SplineEntryList Spline::Generate(const SplineEntryList& entry_list, int nsub) nflip = qsum>psum; for(int cc=cstart;cc<c;++cc) { - sublist[cc].nflip=nflip; + sublist.at(c).nflip=nflip; } } else { ++c; diff --git a/modules/gfx/src/impl/entity_renderer.hh b/modules/gfx/src/impl/entity_renderer.hh index 2fa91e110442b022a0c64d3ad0cc2963d10f1641..4d90f97e0a3542b50473956b378a923268af3121 100644 --- a/modules/gfx/src/impl/entity_renderer.hh +++ b/modules/gfx/src/impl/entity_renderer.hh @@ -180,6 +180,7 @@ protected: DirtyFlags sel_state_; DirtyFlags state_; unsigned int debug_flags_; + float opacity_; }; //Simplify color ops diff --git a/modules/gfx/src/impl/line_trace_renderer.cc b/modules/gfx/src/impl/line_trace_renderer.cc index b0279b71f0f274f101757c0e2c321fc102e4c3e2..45e2b63fa7e013df3c2e78653764c83312be4693 100644 --- a/modules/gfx/src/impl/line_trace_renderer.cc +++ b/modules/gfx/src/impl/line_trace_renderer.cc @@ -17,12 +17,16 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #include "line_trace_renderer.hh" #include <ost/gfx/entity.hh> namespace ost { namespace gfx { namespace impl { -LineTraceRenderer::LineTraceRenderer(BackboneTrace& trace): +LineTraceRenderer::LineTraceRenderer(BackboneTrace* trace): TraceRendererBase(trace, 1), options_(new LineTraceRenderOptions()) { this->SetName("Fast Trace"); @@ -41,10 +45,9 @@ void LineTraceRenderer::PrepareRendering() } } -void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset, +void LineTraceRenderer::PrepareRendering(const BackboneTrace& trace_subset, IndexedVertexArray& va, bool is_sel) { - const Color& sel_clr=this->GetSelectionColor(); if(options_!=NULL){ va.Clear(); @@ -56,54 +59,27 @@ void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset, va.SetLineWidth(options_->GetLineWidth()); va.SetPointSize(options_->GetLineWidth()); va.SetAALines(options_->GetAALines()); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { - const NodeListSubset& nl=trace_subset[node_list]; - - if (nl.GetSize()==2) { - VertexID p0, p1; - if (nl.AtStart()==0) { - p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : nl[0].color1); - p1=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, - geom::Vec3(), is_sel ? sel_clr : nl[1].color1); - } else { - p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, - geom::Vec3(), is_sel ? sel_clr : nl[0].color1); - p1=va.Add(nl[1].atom.GetPos(), - geom::Vec3(), is_sel ? sel_clr : nl[1].color1); - } - va.AddLine(p0, p1); - continue; - } - if (nl.GetSize()<3) { - continue; - } - VertexID p0; - if (nl.AtStart()==0) { - p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : nl[0].color1); - } else { - p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, - geom::Vec3(), is_sel ? sel_clr : nl[0].color1); + for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { + const NodeEntryList& nl=trace_subset.GetList(node_list); + + if (nl.size()<2) { + continue; } - for (int i=1; i<nl.GetSize()-1;++i) { + + VertexID p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(), + is_sel ? sel_clr : nl[0].color1); + + for (unsigned int i=1; i<nl.size()-1;++i) { const NodeEntry& entry=nl[i]; VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), is_sel ? sel_clr : entry.color1); va.AddLine(p0, p1); p0=p1; } - const NodeEntry& entry=nl[nl.GetSize()-1]; - if (nl.AtEnd()==0) { - VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : entry.color1); - va.AddLine(p0, p1); - } else { - geom::Vec3 p=(entry.atom.GetPos()+nl[nl.GetSize()-2].atom.GetPos())*0.5; - VertexID p1 =va.Add(p, geom::Vec3(), - is_sel ? sel_clr : entry.color1); - va.AddLine(p0, p1); - } + const NodeEntry& entry=nl.back(); + VertexID p1 =va.Add(entry.atom.GetPos(), geom::Vec3(), + is_sel ? sel_clr : entry.color1); + va.AddLine(p0, p1); } } sel_state_=0; @@ -112,7 +88,6 @@ void LineTraceRenderer::PrepareRendering(TraceSubset& trace_subset, void LineTraceRenderer::Render() { - } bool LineTraceRenderer::CanSetOptions(RenderOptionsPtr& render_options) diff --git a/modules/gfx/src/impl/line_trace_renderer.hh b/modules/gfx/src/impl/line_trace_renderer.hh index d4b904e0fa478286e1bcb7f47e677f6772051344..fc2a2ad87b951e4f7e9788f1fb8aa66ff38f28dc 100644 --- a/modules/gfx/src/impl/line_trace_renderer.hh +++ b/modules/gfx/src/impl/line_trace_renderer.hh @@ -16,6 +16,11 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #ifndef OST_GFX_IMPL_LINE_TRACE_RENDERER_HH #define OST_GFX_IMPL_LINE_TRACE_RENDERER_HH @@ -36,10 +41,10 @@ using namespace impl; /// \internal class DLLEXPORT_OST_GFX LineTraceRenderer: public TraceRendererBase { public: - LineTraceRenderer(BackboneTrace& trace); + LineTraceRenderer(BackboneTrace* trace); virtual void PrepareRendering(); - virtual void PrepareRendering(TraceSubset& trace_subset, + virtual void PrepareRendering(const BackboneTrace& trace_subset, IndexedVertexArray& va, bool is_sel); virtual void Render(); diff --git a/modules/gfx/src/impl/map_octree.cc b/modules/gfx/src/impl/map_octree.cc index be5f7a8db5c6f8b27a9454bf7c21fb1b7cfb52d6..33bd93d71ae00f0601015b6ba0571b96621e7a62 100644 --- a/modules/gfx/src/impl/map_octree.cc +++ b/modules/gfx/src/impl/map_octree.cc @@ -94,7 +94,7 @@ std::pair<float,float> MapOctree::BuildOctreeRec(const OcRangeVector& range_vec, } assert(parent.IsLeaf()==false); if (levels_.size()<=level) { - levels_.push_back(OcNodeList()); + levels_.push_back(OcNodeEntryList()); levels_.back().reserve(this->GetNumNodesForLevel(level)); assert(level<9 && "MAP TOO BIG for Octree"); } diff --git a/modules/gfx/src/impl/map_octree.hh b/modules/gfx/src/impl/map_octree.hh index 08a2c57c210f41524b2faa7e5ee24a81c3fd9412..999219e83880049f6df6e0f4c0cde3d9558fd778 100644 --- a/modules/gfx/src/impl/map_octree.hh +++ b/modules/gfx/src/impl/map_octree.hh @@ -97,7 +97,7 @@ private: float max_; // < maximum value of voxels inside OctreeNode }; -typedef std::vector<OctreeNode> OcNodeList; +typedef std::vector<OctreeNode> OcNodeEntryList; /// \brief Octree datastructure for 3D images @@ -215,7 +215,7 @@ private: OctreeNode& parent); img::ImageHandle map_; - std::vector<OcNodeList> levels_; + std::vector<OcNodeEntryList> levels_; }; }}} diff --git a/modules/gfx/src/impl/sline_renderer.cc b/modules/gfx/src/impl/sline_renderer.cc index a558bc6732f27c4a283beab4dfbeaa34763d9fe4..7ae7f937a99eaf5dd374486f9976ccf41b0938e6 100644 --- a/modules/gfx/src/impl/sline_renderer.cc +++ b/modules/gfx/src/impl/sline_renderer.cc @@ -16,13 +16,18 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #include "sline_renderer.hh" #include <ost/gfx/entity.hh> namespace ost { namespace gfx { namespace impl { -SlineRenderer::SlineRenderer(BackboneTrace& trace): +SlineRenderer::SlineRenderer(BackboneTrace* trace): TraceRendererBase(trace, 3), options_(new SlineRenderOptions()) { this->SetName("Fast Spline"); @@ -40,7 +45,7 @@ void SlineRenderer::PrepareRendering() } } -void SlineRenderer::PrepareRendering(TraceSubset& trace_subset, +void SlineRenderer::PrepareRendering(const BackboneTrace& trace_subset, IndexedVertexArray& va, bool is_sel) { const Color& sel_clr=this->GetSelectionColor(); @@ -56,12 +61,12 @@ void SlineRenderer::PrepareRendering(TraceSubset& trace_subset, va.SetLineWidth(options_->GetLineWidth()); va.SetPointSize(options_->GetLineWidth()); va.SetAALines(options_->GetAALines()); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { + for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { // first build the spline SplineEntryList spl; - const NodeListSubset& nl=trace_subset[node_list]; - assert(nl.GetSize() && "node list subset with zero eles encountered!"); - for (int i=0; i<nl.GetSize();++i) { + const NodeEntryList& nl=trace_subset.GetList(node_list); + if(nl.empty()) continue; + for (unsigned int i=0; i<nl.size();++i) { const NodeEntry& entry=nl[i]; SplineEntry ee(entry.atom.GetPos(), entry.direction, entry.normal, entry.rad, @@ -71,16 +76,9 @@ void SlineRenderer::PrepareRendering(TraceSubset& trace_subset, spl.push_back(ee); } SplineEntryList sel = Spline::Generate(spl,spline_detail); - SplineEntryList::const_iterator sit=sel.begin(), - send=sel.end()-spline_detail+1; - if (nl.AtStart()>0) { - sit+=nl.AtStart()*spline_detail-spline_detail/2; - } - if (nl.AtEnd()>0) { - send-=nl.AtEnd()*spline_detail-spline_detail/2; - } + SplineEntryList::const_iterator sit=sel.begin(); VertexID p0=va.Add(sit->position, geom::Vec3(),sit->color1); - for (++sit; sit<send; ++sit) { + for (++sit; sit!=sel.end(); ++sit) { VertexID p1 = va.Add(sit->position, geom::Vec3(),sit->color1); va.AddLine(p0,p1); p0=p1; diff --git a/modules/gfx/src/impl/sline_renderer.hh b/modules/gfx/src/impl/sline_renderer.hh index b264fc4b61f99088f595c4e5df6bb42977b19a31..4c08ba3b0fe587960af2b0a48fe808c84e8ed629 100644 --- a/modules/gfx/src/impl/sline_renderer.hh +++ b/modules/gfx/src/impl/sline_renderer.hh @@ -16,6 +16,11 @@ // along with this library; if not, write to the Free Software Foundation, Inc., // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ + +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #ifndef OST_GFX_SLINE_RENDERER_HH #define OST_GFX_SLINE_RENDERER_HH @@ -32,7 +37,7 @@ namespace ost { namespace gfx { namespace impl { /// \internal class DLLEXPORT_OST_GFX SlineRenderer: public TraceRendererBase { public: - SlineRenderer(BackboneTrace& trace); + SlineRenderer(BackboneTrace* trace); virtual void PrepareRendering(); @@ -43,7 +48,7 @@ public: virtual ~SlineRenderer(); private: - void PrepareRendering(TraceSubset& subset, IndexedVertexArray& va, + void PrepareRendering(const BackboneTrace& subset, IndexedVertexArray& va, bool is_sel); SlineRenderOptionsPtr options_; }; diff --git a/modules/gfx/src/impl/trace_renderer.cc b/modules/gfx/src/impl/trace_renderer.cc index 29691cc1d39bc669628ab6bf7e211d22f8d52fee..eacf3f0a99a6fb38e6e87326c5630ee1fefd17e5 100644 --- a/modules/gfx/src/impl/trace_renderer.cc +++ b/modules/gfx/src/impl/trace_renderer.cc @@ -17,6 +17,10 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #include <ost/gfx/entity.hh> #include <ost/gfx/povray.hh> @@ -25,7 +29,7 @@ namespace ost { namespace gfx { namespace impl { -TraceRenderer::TraceRenderer(BackboneTrace& trace): +TraceRenderer::TraceRenderer(BackboneTrace* trace): TraceRendererBase(trace, 1), options_(new TraceRenderOptions()) { this->SetName("Trace"); @@ -43,8 +47,7 @@ void TraceRenderer::PrepareRendering() } } -#if 1 -void TraceRenderer::PrepareRendering(TraceSubset& trace_subset, +void TraceRenderer::PrepareRendering(BackboneTrace& trace_subset, IndexedVertexArray& va, bool is_sel) { float plus=is_sel ? 0.05: 0.0; @@ -55,14 +58,14 @@ void TraceRenderer::PrepareRendering(TraceSubset& trace_subset, va.SetCullFace(true); va.SetColorMaterial(true); va.SetTwoSided(false); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { - const NodeListSubset& nl=trace_subset[node_list]; + for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { + const NodeEntryList& nl=trace_subset.GetList(node_list); mol::AtomHandle a1=nl[0].atom; va.AddSphere(SpherePrim(a1.GetPos(), options_->GetTubeRadius()+plus, is_sel ? sel_clr : nl[0].color1), options_->GetArcDetail()); - for(int i=1;i<nl.GetSize();++i) { + for(unsigned int i=1;i<nl.size();++i) { mol::AtomHandle a2=nl[i].atom; va.AddSphere(SpherePrim(a2.GetPos(), options_->GetTubeRadius()+plus, @@ -83,169 +86,18 @@ void TraceRenderer::PrepareRendering(TraceSubset& trace_subset, state_=0; } -#else - -void TraceRenderer::PrepareRendering(TraceSubset& trace_subset, - IndexedVertexArray& va, bool is_sel) -{ - const Color& sel_clr=this->GetSelectionColor(); - float radius=options_->GetTubeRadius(); - if (is_sel) { - radius+=0.1; - } - int n=8*options_->GetArcDetail(); - if(options_!=NULL) { - va.SetLighting(true); - va.SetCullFace(false); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { - const NodeListSubset& nl=trace_subset[node_list]; - geom::Vec3 cursor_pos; - geom::Mat3 cursor_ori; - if (nl.GetSize()==2) { - VertexID p0, p1; - if (nl.AtStart()==0) { - p0=va.Add(nl[0].atom.GetPos(), geom::Vec3(), - is_sel ? sel_clr : nl[0].color1); - p1=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, - geom::Vec3(), is_sel ? sel_clr : nl[1].color1); - } else { - p0=va.Add((nl[0].atom.GetPos()+nl[1].atom.GetPos())/2, - geom::Vec3(), is_sel ? sel_clr : nl[0].color1); - p1=va.Add(nl[1].atom.GetPos(), - geom::Vec3(), is_sel ? sel_clr : nl[1].color1); - } - va.AddLine(p0, p1); - continue; - } - if (nl.GetSize()<3) { - continue; - } - VertexID p0; - geom::Vec3 z=geom::Normalize(nl[1].atom.GetPos()-nl[0].atom.GetPos()); - geom::Vec3 y=geom::OrthogonalVector(z); - geom::Vec3 x=geom::Cross(y, z); - cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1], - x[2], y[2], z[2]); - if (nl.AtStart()==0) { - cursor_pos=nl[0].atom.GetPos(); - } else { - cursor_pos=(nl[0].atom.GetPos()+nl[1].atom.GetPos())/2; - } - p0=this->AddCappedProfile(va, is_sel? sel_clr : nl[0].color1, - cursor_pos, cursor_ori, radius, true, n); - for (int i=1; i<nl.GetSize()-1;++i) { - const NodeEntry& entry=nl[i]; - geom::Vec3 old_dir=geom::Normalize(entry.atom.GetPos()-cursor_pos); - cursor_pos=entry.atom.GetPos(); - - geom::Vec3 z=geom::Normalize(nl[i+1].atom.GetPos()-cursor_pos); - geom::Vec3 y=geom::Normalize(geom::Cross(z, cursor_ori.GetCol(0))); - geom::Vec3 x=geom::Normalize(geom::Cross(y, z)); - geom::Vec3 iz=geom::Normalize(cursor_ori.GetCol(2)+z); - - geom::Vec3 iy=geom::Normalize(geom::Cross(cursor_ori.GetCol(2), z)); - geom::Vec3 ix=geom::Normalize(geom::Cross(iy, iz)); - - geom::Mat3 i_ori=geom::Mat3(ix[0], iy[0], iz[0], ix[1], iy[1], iz[1], - ix[2], iy[2], iz[2]); - cursor_ori=geom::Mat3(x[0], y[0], z[0], x[1], y[1], z[1], - x[2], y[2], z[2]); - // TODO. The intersection of two cylinders is an ellipse. Use an - // elliptic profile instead of a circular profile. - VertexID p1=this->AddCircularProfile(va, is_sel ? sel_clr : entry.color1, - cursor_pos, i_ori, radius, n); - this->ConnectProfiles(p0, p1, n, old_dir, va); - p0=p1; - } - const NodeEntry& entry=nl[nl.GetSize()-1]; - if (nl.AtEnd()==0) { - cursor_pos=entry.atom.GetPos(); - } else { - cursor_pos=(entry.atom.GetPos()+nl[nl.GetSize()-2].atom.GetPos())*0.5; - } - VertexID p1 =this->AddCappedProfile(va, is_sel ? sel_clr : entry.color1, - cursor_pos, cursor_ori, - radius, false, n); - this->ConnectProfiles(p0, p1, n, cursor_ori.GetCol(2), va); - } - } - sel_state_=0; - state_=0; -} -#endif - -VertexID TraceRenderer::AddCappedProfile(IndexedVertexArray& va, - const Color& color, - const geom::Vec3& center, - const geom::Mat3& ori, float radius, - bool flip_normal, - int n) -{ - VertexID center_id=va.Add(center, geom::Vec3(), color); - VertexID first=this->AddCircularProfile(va, color, center, ori, radius, n); - for (int i=0; i<n; ++i) { - va.AddTriN(center_id, first+i, first+((i+1) % n)); - } - return first; -} - -VertexID TraceRenderer::AddCircularProfile(IndexedVertexArray& va, - const Color& color, - const geom::Vec3& center, - const geom::Mat3& ori, - float radius, - int n) -{ - float delta_angle=2*M_PI/n; - VertexID f=0; - geom::Vec3 normal=ori.GetRow(2); - for (int i=0; i<n; ++i) { - geom::Vec3 normal=ori*geom::Vec3(cos(i*delta_angle), - sin(i*delta_angle), 0.0); - VertexID x=va.Add(center+normal*radius, normal, color); - if (i==0) { - f=x; - } - } - return f; -} - -void TraceRenderer::ConnectProfiles(VertexID prof0, VertexID prof1, int n, - const geom::Vec3& dir, - IndexedVertexArray& va) -{ - // avoid twisting - int off=0; - float best=0.0; - geom::Vec3 pp=va.GetVert(prof0); - for (int i=0; i<n; ++i) { - geom::Vec3 dir2=geom::Normalize(va.GetVert(prof1+i)-pp); - float dot=fabs(geom::Dot(dir, dir2)); - if (best<dot) { - best=dot; - off=i; - } - } - for (int i=0; i<n; ++i) { - VertexID i1=prof1+((i+off) % n), i2=prof1+((i+off+1) % n); - VertexID i3=prof0+i, i4=prof0+((i+1)%n); - va.AddTriN(i1, i2, i3); - va.AddTriN(i2, i3, i4); - } -} - void TraceRenderer::RenderPov(PovState& pov, const std::string& name) { pov.write_merge_or_union(name); - for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) { - const NodeListSubset& nl=trace_subset_[node_list]; + for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) { + const NodeEntryList& nl=trace_subset_.GetList(node_list); geom::Vec3 p0=nl[0].atom.GetPos(); float rad0=0.2; Color col0=nl[0].color1; pov.write_sphere(p0,rad0,col0,name); - for (int i=1; i<nl.GetSize();++i) { + for (unsigned int i=1; i<nl.size();++i) { geom::Vec3 p1=nl[i].atom.GetPos(); float rad1=0.2; Color col1=nl[i].color1; @@ -262,11 +114,6 @@ void TraceRenderer::RenderPov(PovState& pov, const std::string& name) pov.inc() << " }\n"; } -void TraceRenderer::Render() -{ - -} - bool TraceRenderer::CanSetOptions(RenderOptionsPtr& render_options) { return render_options.get()->GetRenderMode()==RenderMode::TRACE; diff --git a/modules/gfx/src/impl/trace_renderer.hh b/modules/gfx/src/impl/trace_renderer.hh index 77cb8d3daa3d1584b45d38ea125bc03f6181a470..e8f9cff3bd1f66650f797f7c29888553dd31371a 100644 --- a/modules/gfx/src/impl/trace_renderer.hh +++ b/modules/gfx/src/impl/trace_renderer.hh @@ -20,8 +20,9 @@ #define OST_GFX_IMPL_TRACE_RENDERER_HH /* - Author: Marco Biasini - */ + Authors: Marco Biasini, Ansgar Philippsen +*/ + #include <ost/gfx/impl/backbone_trace.hh> #include <ost/gfx/impl/entity_detail.hh> #include <ost/gfx/impl/trace_renderer_base.hh> @@ -37,12 +38,12 @@ using namespace impl; /// \internal class DLLEXPORT_OST_GFX TraceRenderer: public TraceRendererBase { public: - TraceRenderer(BackboneTrace& trace); + TraceRenderer(BackboneTrace* trace); virtual void PrepareRendering(); - virtual void PrepareRendering(TraceSubset& trace_subset, + virtual void PrepareRendering(BackboneTrace& trace_subset, IndexedVertexArray& va, bool is_sel); - virtual void Render(); + virtual void RenderPov(PovState& pov, const std::string& name); virtual bool CanSetOptions(RenderOptionsPtr& render_options); @@ -51,14 +52,6 @@ public: virtual ~TraceRenderer(); private: - VertexID AddCappedProfile(IndexedVertexArray& va, const Color& color, - const geom::Vec3& center, const geom::Mat3& ori, - float radius, bool flip_normal, int n); - VertexID AddCircularProfile(IndexedVertexArray& va, const Color& color, - const geom::Vec3& center, const geom::Mat3& ori, - float radius, int n); - void ConnectProfiles(VertexID prof1, VertexID prof2, int n, - const geom::Vec3& dir, IndexedVertexArray& va); TraceRenderOptionsPtr options_; }; diff --git a/modules/gfx/src/impl/trace_renderer_base.cc b/modules/gfx/src/impl/trace_renderer_base.cc index 7fa679e88e98393087a4f79d3b02df46a60effaf..9231e929c5c791fc823bfbb8afc108b14d32319d 100644 --- a/modules/gfx/src/impl/trace_renderer_base.cc +++ b/modules/gfx/src/impl/trace_renderer_base.cc @@ -17,6 +17,10 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA //------------------------------------------------------------------------------ +/* + Authors: Marco Biasini, Ansgar Philippsen +*/ + #include <ost/gfx/scene.hh> #include "trace_renderer_base.hh" @@ -34,15 +38,15 @@ void set_node_entry_color(NodeEntry& e, ColorMask mask, } template <typename T1> -inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T1 get_col, const ColorOp& op) +inline void apply_color_op(TraceRendererBase* rend, BackboneTrace& trace_subset, T1 get_col, const ColorOp& op) { rend->UpdateViews(); ColorMask mask = op.GetMask(); if(op.IsSelectionOnly()){ mol::Query q(op.GetSelection()); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { - NodeListSubset& nl=trace_subset[node_list]; - for (int i=0; i<nl.GetSize();++i) { + for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { + NodeEntryList& nl=trace_subset.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { if (q.IsAtomSelected(nl[i].atom)) { Color clr =get_col.ColorOfAtom(nl[i].atom); set_node_entry_color(nl[i],mask,clr); @@ -52,9 +56,9 @@ inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T } else{ mol::EntityView view = op.GetView(); - for (int node_list=0; node_list<trace_subset.GetSize(); ++node_list) { - NodeListSubset& nl=trace_subset[node_list]; - for (int i=0; i<nl.GetSize();++i) { + for (int node_list=0; node_list<trace_subset.GetListCount(); ++node_list) { + NodeEntryList& nl=trace_subset.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { if(view.FindAtom(nl[i].atom)){ Color clr =get_col.ColorOfAtom(nl[i].atom); set_node_entry_color(nl[i],mask,clr); @@ -67,8 +71,8 @@ inline void apply_color_op(TraceRendererBase* rend, TraceSubset& trace_subset, T } //ns -TraceRendererBase::TraceRendererBase(BackboneTrace& trace, int n): - trace_(trace), trace_subset_(trace, n), sel_subset_(trace, n) +TraceRendererBase::TraceRendererBase(BackboneTrace* trace, int n): + trace_(trace), trace_subset_(*trace), sel_subset_() { } @@ -80,43 +84,37 @@ void TraceRendererBase::UpdateViews() { if (state_ & DIRTY_VIEW) { mol::EntityView view=this->GetEffectiveView(); - trace_subset_.Update(view); + trace_subset_=trace_->CreateSubset(view); state_&=~DIRTY_VIEW; } if (this->HasSelection() && (sel_state_ & DIRTY_VIEW)) { - sel_subset_.Update(sel_); + sel_subset_ = trace_->CreateSubset(sel_); sel_state_&=~DIRTY_VIEW; } } geom::AlignedCuboid TraceRendererBase::GetBoundingBox() const { - geom::Vec3 mmin, mmax; + geom::Vec3 mmin(std::numeric_limits<float>::max(), + std::numeric_limits<float>::max(), + std::numeric_limits<float>::max()); + geom::Vec3 mmax(-std::numeric_limits<float>::max(), + -std::numeric_limits<float>::max(), + -std::numeric_limits<float>::max()); + assert(!(state_ & DIRTY_VIEW)); - bool empty=true; - for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) { - // first build the spline - const NodeListSubset& nl=trace_subset_[node_list]; - for (int i=0; i<nl.GetSize();++i) { + for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) { + const NodeEntryList& nl=trace_subset_.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { const NodeEntry& entry=nl[i]; - empty=false; geom::Vec3 p=entry.atom.GetPos(); - if (node_list+i==0) { - mmin=p; - mmax=p; - } else { - mmin=geom::Min(mmin, p); - mmax=geom::Max(mmax, p); - } + mmin=geom::Min(mmin, p); + mmax=geom::Max(mmax, p); } } - if (empty) { - throw Error("Can't calculate bounding box of empty renderer"); - } return geom::AlignedCuboid(mmin, mmax); } - void TraceRendererBase::Apply(const gfx::ByElementColorOp& op) { apply_color_op(this,trace_subset_,ByElementGetCol(),op); @@ -151,16 +149,16 @@ void TraceRendererBase::Apply(const gfx::EntityViewColorOp& op) bool TraceRendererBase::HasDataToRender() const { assert(!(state_ & DIRTY_VIEW)); - return this->trace_subset_.GetSize()>0; + return this->trace_subset_.GetListCount()>0; } void TraceRendererBase::set_node_colors(const Color& col, const mol::Query& q, ColorMask mask) { this->UpdateViews(); - for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) { - NodeListSubset& nl=trace_subset_[node_list]; - for (int i=0; i<nl.GetSize();++i) { + for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) { + NodeEntryList& nl=trace_subset_.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { if(q.IsAtomSelected(nl[i].atom)) { set_node_entry_color(nl[i],mask,col); } @@ -169,13 +167,6 @@ void TraceRendererBase::set_node_colors(const Color& col, const mol::Query& q, state_|=DIRTY_VA; } -void TraceRendererBase::set_node_entry_color(NodeEntry& e, ColorMask mask, - const Color& c) -{ - if (mask & MAIN_COLOR) e.color1=c; - if (mask & DETAIL_COLOR) e.color2=c; -} - void TraceRendererBase::PickAtom(const geom::Line3& line, Real line_width, mol::AtomHandle& picked_atom) { @@ -189,9 +180,9 @@ void TraceRendererBase::PickAtom(const geom::Line3& line, Real line_width, } mol::AtomHandle atom; - for (int node_list=0; node_list<trace_subset_.GetSize(); ++node_list) { - NodeListSubset& nl=trace_subset_[node_list]; - for (int i=0; i<nl.GetSize();++i) { + for (int node_list=0; node_list<trace_subset_.GetListCount(); ++node_list) { + NodeEntryList& nl=trace_subset_.GetList(node_list); + for (unsigned int i=0; i<nl.size();++i) { geom::Vec3 p=nl[i].atom.GetPos(); float dist = geom::Distance(line, p); if(dist<=max_dist) { diff --git a/modules/gfx/src/impl/trace_renderer_base.hh b/modules/gfx/src/impl/trace_renderer_base.hh index b102e1cc2c78c5ad1f2881e8530f51fb21a1b205..36e3b960270fa1c1882ae67c9b288eb77ed3613a 100644 --- a/modules/gfx/src/impl/trace_renderer_base.hh +++ b/modules/gfx/src/impl/trace_renderer_base.hh @@ -20,8 +20,8 @@ #define OST_GFX_IMPL_TRACE_RENDERER_BASE_HH /* - Author: Marco Biasini - */ + Authors: Marco Biasini, Ansgar Philippsen +*/ #include <ost/gfx/module_config.hh> #include <ost/gfx/impl/entity_renderer.hh> @@ -35,11 +35,11 @@ namespace ost { namespace gfx { namespace impl { /// \ref "line trace" LineTraceRenderer and /// \ref "smooth trace" SlineRenderer. /// -/// The trace-based entity renderer share a common instance of BackboneTrace -/// that encapulates a smoothed C-alpha trace. +/// All trace-based entity renderers share a common instance of BackboneTrace +/// (which is held by gfx::Entity); it encapulates a smoothed C-alpha trace. class DLLEXPORT_OST_GFX TraceRendererBase : public EntityRenderer { public: - TraceRendererBase(BackboneTrace& trace, int overshoot); + TraceRendererBase(BackboneTrace* trace, int overshoot); virtual geom::AlignedCuboid GetBoundingBox() const; @@ -63,12 +63,10 @@ public: protected: void set_node_colors(const Color& c, const mol::Query& q, ColorMask mask); - void set_node_entry_color(NodeEntry& e, ColorMask mask, const Color& c); - - BackboneTrace& trace_; - TraceSubset trace_subset_; - TraceSubset sel_subset_; + BackboneTrace* trace_; + BackboneTrace trace_subset_; + BackboneTrace sel_subset_; }; }}} diff --git a/modules/gfx/src/render_options/cpk_render_options.cc b/modules/gfx/src/render_options/cpk_render_options.cc index 611db0f48b7de674a82ceb956bec2589bbb23dd8..797fcf760bcd87fd731d5b4eb82a05e3d7547abf 100644 --- a/modules/gfx/src/render_options/cpk_render_options.cc +++ b/modules/gfx/src/render_options/cpk_render_options.cc @@ -28,7 +28,7 @@ namespace gfx { CPKRenderOptions::CPKRenderOptions(): sphere_detail_(4) { #if OST_SHADER_SUPPORT_ENABLED - cpk_mode_=1; + cpk_mode_=0; #else cpk_mode_=0; #endif diff --git a/modules/gfx/src/render_pass.hh b/modules/gfx/src/render_pass.hh index dd7a34a330b0ed36b817ce61f4b5131bdd31385c..00c5f7c23846a4b381b54a0aafdbcbc3d4481e22 100644 --- a/modules/gfx/src/render_pass.hh +++ b/modules/gfx/src/render_pass.hh @@ -33,8 +33,10 @@ typedef enum { /// \brief renders objects with solid color as used for shadow map /// generation OPAQUE_RENDER_PASS, + /// \ brief for transparent objects + TRANSPARENT_RENDER_PASS } RenderPass; }} -#endif \ No newline at end of file +#endif diff --git a/modules/gfx/src/vertex_array.cc b/modules/gfx/src/vertex_array.cc index 8ba36be18b7427d2bd05085b110a979f8da2adcc..06d9123eee509c02fd87e4f564268cf216e6b308 100644 --- a/modules/gfx/src/vertex_array.cc +++ b/modules/gfx/src/vertex_array.cc @@ -562,13 +562,16 @@ void IndexedVertexArray::RenderGL() namespace { unsigned int col_to_index(float* c) { - return static_cast<unsigned int>(c[0]*7.0)*64+static_cast<unsigned int>(c[1]*7.0)*8+static_cast<unsigned int>(c[2]*7.0); + // don't look too closely - I am lacking sufficient caffeine to do this more elegantly + int ret= std::max(0,std::min<int>(511,static_cast<int>(round(c[0]*7.0f))*64+static_cast<int>(round(c[1]*7.0f))*8+static_cast<unsigned int>(round(c[2]*7.0f)))); + return static_cast<unsigned int>(ret); } } void IndexedVertexArray::RenderPov(PovState& pov, const std::string& name) { if(entry_list_.empty()) return; + pov.inc() << "mesh2 {\n"; pov.inc() << " vertex_vectors { " << entry_list_.size() << ",\n";