Something went wrong on our end
-
stefan authored
git-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1769 5a81b35b-ba03-0410-adc8-b2c5c5119f08
stefan authoredgit-svn-id: https://dng.biozentrum.unibas.ch/svn/openstructure/trunk@1769 5a81b35b-ba03-0410-adc8-b2c5c5119f08
entity.cc 25.31 KiB
//------------------------------------------------------------------------------
// This file is part of the OpenStructure project <www.openstructure.org>
//
// Copyright (C) 2008-2010 by the OpenStructure authors
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License as published by the Free
// Software Foundation; either version 3.0 of the License, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//------------------------------------------------------------------------------
/*
Authors: Ansgar Philippsen, Marco Biasini
*/
#include <cmath>
#include <limits>
#include <vector>
#include <iostream>
#include <sstream>
#include <boost/pointer_cast.hpp>
#include "gl_helper.hh"
#include <ost/log.hh>
#include <ost/dyn_cast.hh>
#include <ost/mol/query.hh>
#include <ost/mol/entity_property_mapper.hh>
#include <ost/mol/view_op.hh>
#include <ost/gfx/impl/cartoon_renderer.hh>
#include <ost/gfx/impl/cpk_renderer.hh>
#include <ost/gfx/impl/custom_renderer.hh>
#include <ost/gfx/impl/debug_renderer.hh>
#include <ost/gfx/impl/simple_renderer.hh>
#include <ost/gfx/impl/sline_renderer.hh>
#include <ost/gfx/impl/trace_renderer.hh>
#include <ost/gfx/impl/line_trace_renderer.hh>
#include <ost/gfx/impl/entity_renderer.hh>
#include "input.hh"
#include "scene.hh"
#include "entity.hh"
#include "vertex_array_helper.hh"
#if OST_SHADER_SUPPORT_ENABLED
#include "shader.hh"
#endif
namespace ost {
using namespace mol;
namespace gfx {
using namespace impl;
Entity::Entity(const String& name,
const EntityHandle& h,
const Query& q):
GfxObj(name),
qv_(q, h),
bbox_(geom::Vec3(), geom::Vec3())
{
init(RenderMode::SIMPLE);
}
Entity::Entity(const String& name,
RenderMode::Type m,
const EntityHandle& h,
const Query& q):
GfxObj(name),
qv_(q, h),
bbox_(geom::Vec3(), geom::Vec3())
{
init(m);
}
Entity::Entity(const String& name,
const EntityView& v):
GfxObj(name),
qv_(v),
bbox_(geom::Vec3(), geom::Vec3())
{
init(RenderMode::SIMPLE);
}
Entity::Entity(const String& name,
RenderMode::Type m,
const EntityView& v):
GfxObj(name),
qv_(v),
bbox_(geom::Vec3(), geom::Vec3())
{
init(m);
}
impl::EntityRenderer* Entity::GetOrCreateRenderer(RenderMode::Type rm)
{
if (renderer_.find(rm)!=renderer_.end()) {
return renderer_.find(rm)->second;
}
impl::EntityRenderer* r=NULL;
switch (rm) {
case RenderMode::SIMPLE:
r=new impl::SimpleRenderer();
break;
case RenderMode::CUSTOM:
r=new impl::CustomRenderer();
break;
case RenderMode::SLINE:
r=new impl::SlineRenderer(trace_);
break;
case RenderMode::LINE_TRACE:
r=new impl::LineTraceRenderer(trace_);
break;
case RenderMode::TRACE:
r=new impl::TraceRenderer(trace_);
break;
case RenderMode::HSC:
r=new impl::CartoonRenderer(trace_);
break;
case RenderMode::CPK:
r=new impl::CPKRenderer();
break;
case RenderMode::TUBE:
r=new impl::CartoonRenderer(trace_, true);
break;
default:
assert(0 && "GetOrCreateRendererer() not implemented for this mode");
}
renderer_.insert(rm, r);
return r;
}
void Entity::init(RenderMode::Type rm)
{
// TODO replace with def mat for this gfx obj type
SetMat(0.0,1.0,0.8,96.0);
update_view_=true;
render_mode_=rm;
trace_.SetView(this->GetView());
sel_=this->GetView().CreateEmptyView();
impl::EntityRenderer* r=this->GetOrCreateRenderer(rm);
r->AddView(this->GetView());
r->UpdateViews();
set_static_max_rad();
Rebuild();
}
namespace {
SimpleRenderOptionsPtr get_sro(impl::EntityRenderer* renderer)
{
impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer);
assert(sr);
return dyn_cast<SimpleRenderOptions>(sr->GetOptions());
}
}
void Entity::SetBlur(bool f)
{
impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
SimpleRenderOptionsPtr sro=get_sro(renderer);
sro->SetBlurFlag(f);
}
void Entity::BlurSnapshot()
{
impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
impl::SimpleRenderer* sr=dynamic_cast<SimpleRenderer*>(renderer);
assert(sr);
sr->BlurSnapshot();
}
void Entity::SetBlurFactors(float bf1,float bf2)
{
impl::EntityRenderer* renderer=this->GetOrCreateRenderer(RenderMode::SIMPLE);
SimpleRenderOptionsPtr sro=get_sro(renderer);
sro->SetBlurFactors(bf1, bf2);
}
void Entity::Rebuild()
{
geom::Vec3 delta=GetTF().GetTrans()-GetTF().GetCenter();
this->ReapplyColorOps();
FlagRebuild();
geom::Vec3 center=this->GetCenter();
Transform tf=this->GetTF();
tf.SetCenter(center);
tf.SetTrans(center+delta);
this->SetTF(tf);
Scene::Instance().RequestRedraw();
}
void Entity::UpdatePositions()
{
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* r=i->second;
r->FlagPositionsDirty();
}
FlagRebuild();
Scene::Instance().RequestRedraw();
}
geom::AlignedCuboid Entity::GetBoundingBox() const
{
this->UpdateIfNeeded();
return bbox_;
}
void Entity::ProcessLimits(geom::Vec3& minc, geom::Vec3& maxc,
const Transform& tf) const
{
try {
geom::AlignedCuboid coord_limits=this->GetBoundingBox();
// update min/max by transforming all 8 corners of the bounding box and
// comparing it against the current min/max
geom::Vec3 mmin=coord_limits.GetMin();
geom::Vec3 mmax=coord_limits.GetMax();
geom::Vec3 t1=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmin[2]));
geom::Vec3 t2=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmin[2]));
geom::Vec3 t3=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmin[2]));
geom::Vec3 t4=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmin[2]));
geom::Vec3 t5=tf.Apply(geom::Vec3(mmin[0], mmin[1], mmax[2]));
geom::Vec3 t6=tf.Apply(geom::Vec3(mmin[0], mmax[1], mmax[2]));
geom::Vec3 t7=tf.Apply(geom::Vec3(mmax[0], mmax[1], mmax[2]));
geom::Vec3 t8=tf.Apply(geom::Vec3(mmax[0], mmin[1], mmax[2]));
minc = geom::Min(minc, geom::Min(t1, geom::Min(t2, geom::Min(t3,
geom::Min(t4, geom::Min(t5, geom::Min(t6,
geom::Min(t7, t8))))))));
maxc = geom::Max(maxc, geom::Max(t1, geom::Max(t2, geom::Max(t3,
geom::Max(t4, geom::Max(t5, geom::Max(t6,
geom::Max(t7, t8))))))));
} catch(Error& e) {
// in case the object is empty...
}
}
void Entity::SetColorForAtom(const Color& col,
const AtomHandle& atom)
{
std::stringstream selection;
selection << "cname='" << atom.GetResidue().GetChain().GetName()
<< "' and rindex=" << atom.GetResidue().GetIndex()
<< " and aname='" << atom.GetName() << "'";
UniformColorOp cop = UniformColorOp(selection.str(), col);
this->Apply(cop);
Scene::Instance().RequestRedraw();
}
void Entity::CacheBoundingBox() const
{
geom::AlignedCuboid coord_limits=geom::AlignedCuboid(geom::Vec3(),
geom::Vec3());
bool has_data=false;
for (RendererMap::const_iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
const impl::EntityRenderer* r=i->second;
if (r->IsEnabled() && r->HasDataToRender()) {
if (!has_data) {
coord_limits=r->GetBoundingBox();
has_data=true;
} else {
coord_limits=geom::Union(coord_limits, r->GetBoundingBox());
}
}
}
bbox_=coord_limits;
}
bool Entity::UpdateIfNeeded() const
{
bool updated=false;
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
EntityRenderer* renderer =i->second;
if (renderer->IsDirty()) {
renderer->PrepareRendering();
updated=true;
}
}
if (updated) {
this->CacheBoundingBox();
}
return updated;
}
void Entity::CustomPreRenderGL(bool update)
{
if (update) {
this->UpdateIfNeeded();
}
}
void Entity::CustomRenderGL(RenderPass pass)
{
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* r=i->second;
if(r->IsEnabled()){
switch(pass) {
case STANDARD_RENDER_PASS:
case OPAQUE_RENDER_PASS:
r->Render(pass);
break;
case GLOW_RENDER_PASS:
if (r->HasSelection()) {
r->Render(pass);
}
break;
}
}
}
geom::AlignedCuboid bbox=this->GetBoundingBox();
geom::Vec3 mmin=bbox.GetMin();
geom::Vec3 mmax=bbox.GetMax();
#if 0
glDisable(GL_LIGHTING);
glLineWidth(1.0);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_LINES);
glVertex3(geom::Vec3(mmin[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmin[0], mmin[1], mmax[2]));
glVertex3(geom::Vec3(mmin[0], mmin[1], mmax[2]));
glVertex3(geom::Vec3(mmin[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmin[2]));
glVertex3(geom::Vec3(mmin[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmax[1], mmax[2]));
glVertex3(geom::Vec3(mmin[0], mmin[1], mmax[2]));
glVertex3(geom::Vec3(mmax[0], mmin[1], mmax[2]));
glEnd();
#endif
}
void Entity::CustomRenderPov(PovState& pov)
{
for (RendererMap::iterator it=renderer_.begin(); it!=renderer_.end(); ++it) {
if(it->second->IsEnabled()){
it->second->RenderPov(pov,GetName());
}
}
}
mol::AtomHandle Entity::PickAtom(const geom::Line3& line, Real line_width)
{
mol::AtomHandle picked_atom;
if (!this->IsVisible())
return picked_atom;
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* r=i->second;
if (r->HasDataToRender() && r->IsEnabled()) {
r->PickAtom(line, line_width, picked_atom);
}
}
return picked_atom;
}
mol::BondHandle Entity::PickBond(const geom::Line3& line, Real line_width)
{
mol::BondHandle picked_bond;
if (!this->IsVisible())
return picked_bond;
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* r=i->second;
if (r->HasDataToRender() && r->IsEnabled()) {
r->PickBond(line, line_width, picked_bond);
}
}
return picked_bond;
}
bool Entity::OnSelect(const geom::Line3& line, geom::Vec3& result,
float zlim, bool pick_flag)
{
uint smode=Scene::Instance().GetSelectionMode();
mol::AtomHandle sel=this->PickAtom(line, 0.5);
if(smode==1 || smode==2 || smode==3) {
if(sel.IsValid()) {
geom::Vec3 ppos = Scene::Instance().Project(sel.GetPos());
if(ppos[2]>zlim) return false;
std::ostringstream os;
os << GetName() << ": " << sel.GetQualifiedName() << " "
<< sel.GetPos();
Scene::Instance().StatusMessage(os.str());
if(!pick_flag) {
result = sel.GetPos();
return true;
}
if(smode==1) {
AtomView av = sel_.FindAtom(sel.GetHandle());
if(av.IsValid()) {
LOGN_DEBUG("de-selected atom: " << sel);
sel_.RemoveAtom(av);
if(av.GetResidue().GetAtomCount()==0){
av.GetResidue().GetChain().RemoveResidue(av.GetResidue());
}
} else {
LOGN_DEBUG("selected atom: " << sel);
sel_.AddAtom(sel.GetHandle());
}
result = sel.GetPos();
} else if(smode==2) {
AtomView av=sel_.FindAtom(sel);
ResidueView rv=sel_.FindResidue(sel.GetResidue());
if(av.IsValid() && rv.IsValid()) {
LOGN_DEBUG("de-selected residue: " << sel.GetResidue());
sel_.RemoveResidue(rv);
} else {
LOGN_DEBUG("selected residue: " << sel.GetResidue());
sel_.AddResidue(sel.GetResidue(),ViewAddFlag::INCLUDE_ALL);
}
AtomHandle ca=sel.GetHandle().GetResidue().GetCentralAtom();
result = ca.IsValid() ? ca.GetPos() : sel.GetPos();
} else {
if (!sel.IsValid()) {
return false;
}
ChainHandle chain=sel.GetHandle().GetResidue().GetChain();
ChainView cv = sel_.FindChain(chain);
if(cv.IsValid()) {
LOGN_DEBUG("de-selected chain: " << chain);
sel_.RemoveChain(cv);
} else {
LOGN_DEBUG("selected chain: " << chain);
sel_.AddChain(chain, ViewAddFlag::INCLUDE_ALL);
}
result = geom::Vec3(); // todo calculate center of mass
}
sel_.AddAllInclusiveBonds();
sel_update_=true;
GfxObjP o=dyn_cast<GfxObj>(shared_from_this());
this->UpdateSelection();
this->FlagRebuild();
Scene::Instance().SelectionChanged(GetName(), sel_);
Scene::Instance().RequestRedraw();
return true;
}
}
if(sel) {
LOGN_MESSAGE("picked " << sel.GetResidue().GetChain().GetName() << " "
<< sel.GetResidue().GetNumber() << " " << sel.GetName());
return true;
}
return false;
}
RenderOptionsPtr Entity::GetOptions(RenderMode::Type render_mode)
{
EntityRenderer* renderer = this->GetOrCreateRenderer(render_mode);
RenderOptionsPtr render_options=renderer->GetOptions();
EntityP e=boost::dynamic_pointer_cast<Entity>(shared_from_this());
render_options->AddObserver(e);
return render_options;
}
void Entity::SetOptions(RenderMode::Type render_mode,
RenderOptionsPtr& render_options)
{
RendererMap::iterator i=renderer_.find(render_mode);
if(i!= renderer_.end()) {
EntityRenderer* entity_renderer =i->second;
if(entity_renderer->CanSetOptions(render_options)){
EntityP e=boost::dynamic_pointer_cast<Entity>(shared_from_this());
RenderOptionsPtr old_render_options = entity_renderer->GetOptions();
old_render_options->RemoveObserver(e);
entity_renderer->SetOptions(render_options);
render_options->AddObserver(e);
FlagRebuild();
Scene::Instance().RequestRedraw();
} else{
throw Error("These render options are not compatible with this render mode.");
}
} else {
throw Error("The render mode does not exist");
}
}
void Entity::ApplyRenderOptions(RenderMode::Type render_mode,
RenderOptionsPtr& render_options)
{
RendererMap::iterator i=renderer_.find(render_mode);
if(i!=renderer_.end()) {
RenderOptionsPtr options=i->second->GetOptions();
if(options->CanApplyRenderOptions(render_options)){
EntityP e=boost::dynamic_pointer_cast<Entity>(shared_from_this());
options->AddObserver(e);
options->ApplyRenderOptions(render_options);
}
else{
throw Error("These render options can not be applied to the given render mode.");
}
}
else {
throw Error("The render mode does not exist");
}
}
void Entity::OptionsChanged(RenderMode::Type render_mode)
{
impl::EntityRenderer* entity_renderer=this->GetOrCreateRenderer(render_mode);
entity_renderer->RenderOptionsChanged();
FlagRebuild();
Scene::Instance().ObjectChanged(this->GetName());
}
void Entity::OnRenderModeChange()
{
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
i->second->ClearViews();
}
impl::EntityRenderer* r=this->GetOrCreateRenderer(render_mode_);
r->AddView(this->GetView());
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
mol::EntityView rv=i->second->GetEffectiveView();
if (rv.IsValid() && rv.GetAtomCount()>0) {
i->second->SetSelection(mol::Intersection(sel_, rv));
}
i->second->UpdateViews();
}
this->ReapplyColorOps();
this->FlagRebuild();
GfxObj::OnRenderModeChange();
}
const String Entity::GetRenderModeName(RenderMode::Type mode){
RendererMap::iterator i=renderer_.find(mode);
String name = "";
if(i!=renderer_.end()) {
impl::EntityRenderer* renderer=i->second;
name = renderer->GetName();
}
return name;
}
void Entity::SetEnableRenderMode(RenderMode::Type mode, bool enable){
RendererMap::iterator i=renderer_.find(mode);
if(i!=renderer_.end()) {
impl::EntityRenderer* renderer=i->second;
if(renderer->IsEnabled() != enable){
renderer->SetEnabled(enable);
this->FlagRebuild();
}
}
}
bool Entity::IsRenderModeEnabled(RenderMode::Type mode){
RendererMap::iterator i=renderer_.find(mode);
if(i!=renderer_.end()) {
impl::EntityRenderer* renderer=i->second;
return renderer->IsEnabled();
}
return false;
}
RenderModeTypes Entity::GetNotEmptyRenderModes(){
std::vector<RenderMode::Type> render_modes;
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
if(i->second->HasDataToRender()){
render_modes.push_back(i->first);
}
}
return render_modes;
}
void Entity::SetRenderMode(RenderMode::Type mode,
const mol::EntityView& view, bool keep)
{
EntityRenderer* rend = this->GetOrCreateRenderer(mode);
rend->AddView(view);
// substract view from all renderers
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* renderer=i->second;
if (!keep && i->first!=mode) {
renderer->SubstractView(view);
}
mol::EntityView rv=renderer->GetEffectiveView();
if (rv.IsValid()) {
renderer->SetSelection(mol::Intersection(sel_, rv));
}
renderer->UpdateViews();
}
this->ReapplyColorOps();
this->FlagRebuild();
Scene::Instance().RenderModeChanged(GetName());
}
mol::EntityView Entity::GetRenderView(RenderMode::Type mode)
{
EntityRenderer* rend = this->GetOrCreateRenderer(mode);
return rend->GetFullView();
}
void Entity::SetRenderMode(RenderMode::Type mode)
{
GfxObj::SetRenderMode(mode);
}
void Entity::SetVisible(const mol::EntityView& view, bool visible){
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* renderer=i->second;
renderer->SetVisible(view, visible);
renderer->UpdateViews();
}
this->ReapplyColorOps();
this->FlagRebuild();
}
void Entity::SetColor(const Color& col, const String& selection)
{
UniformColorOp cop = UniformColorOp(selection, col);
this->Apply(cop);
}
void Entity::SetDetailColor(const Color& col, const String& selection)
{
UniformColorOp cop = UniformColorOp(selection, col);
cop.SetMask(DETAIL_COLOR);
this->Apply(cop);
}
/// \brief set selection
void Entity::SetSelection(const mol::EntityView& view)
{
if (!view.IsValid()) {
sel_=this->GetView().CreateEmptyView();
} else {
sel_=view;
}
this->UpdateSelection();
this->FlagRebuild();
Scene::Instance().SelectionChanged(GetName(), view);
Scene::Instance().RequestRedraw();
}
void Entity::UpdateSelection()
{
for (RendererMap::iterator i=renderer_.begin(),
e=renderer_.end(); i!=e; ++i) {
impl::EntityRenderer* renderer=i->second;
if (renderer->HasDataToRender()) {
renderer->SetSelection(mol::Intersection(renderer->GetEffectiveView(), sel_));
renderer->UpdateViews();
}
}
}
/// \brief get selection
mol::EntityView Entity::GetSelection() const
{
return sel_;
}
void Entity::ColorByElement()
{
ByElementColorOp cop = ByElementColorOp();
this->Apply(cop);
}
void Entity::ColorBy(const mol::EntityView& ev,
const String& prop,
const Gradient& g, float minv, float maxv)
{
EntityViewColorOp evop = EntityViewColorOp(prop, g,minv,maxv,ev);
this->Apply(evop);
}
#if OST_IMG_ENABLED
void Entity::ColorBy(const img::MapHandle& mh,
const String& prop,
const Gradient& g,float minv, float maxv)
{
MapHandleColorOp mhop = MapHandleColorOp("",prop,g,minv,maxv,mh);
this->Apply(mhop);
}
#endif //OST_IMG_ENABLED
void Entity::ColorBy(const String& prop,
const Gradient& gradient,
float minv,float maxv,
mol::Prop::Level level)
{
GradientLevelColorOp glop = GradientLevelColorOp("",prop, gradient,minv,maxv,level);
this->Apply(glop);
}
void Entity::ColorBy(const String& prop,
const Color& c1, const Color& c2,
float minv, float maxv,
mol::Prop::Level level)
{
Gradient g;
g.SetColorAt(0.0,c1);
g.SetColorAt(1.0,c2);
this->ColorBy(prop,g,minv,maxv,level);
}
void Entity::ColorBy(const String& prop,
const Gradient& gradient,
mol::Prop::Level level)
{
GradientLevelColorOp glop = GradientLevelColorOp("",prop, gradient,level);
this->Apply(glop);
}
mol::EntityView Entity::GetView() const
{
if (update_view_) {
update_view_=false;
cached_view_=qv_.GetEntityView();
}
return cached_view_;
}
void Entity::ColorBy(const String& prop,
const Color& c1, const Color& c2,
mol::Prop::Level level)
{
std::pair<float,float> minmax = this->GetView().GetMinMax(prop);
this->ColorBy(prop,c1,c2,minmax.first, minmax.second,level);
}
void Entity::RadiusBy(const String& prop,
float rmin, float rmax,
float minv, float maxv,
mol::Prop::Level hint)
{
set_static_max_rad();
EntityPropertyMapper epm(prop, hint);
#if 0
for(NodeEntryListList::iterator ll_it=node_list_list_->begin();ll_it!=node_list_list_->end();++ll_it) {
for(NodeEntryList::iterator it=(*ll_it).begin();it!=(*ll_it).end();++it) {
try {
it->rad=clamp(normalize(epm.Get(it->atom), minv, maxv),0.0,1.0)*(rmax-rmin)+rmin;
max_rad_=std::max(max_rad_,it->rad);
} catch (std::exception&) {
LOGN_DEBUG("property " << prop << " not found");
}
}
}
#endif
FlagRebuild();
}
void Entity::RadiusBy(const String& prop,
float rmin, float rmax,
mol::Prop::Level hint)
{
std::pair<float,float> minmax = this->GetView().GetMinMax(prop);
RadiusBy(prop,rmin,rmax,minmax.first,minmax.second,hint);
}
void Entity::ResetRadiusBy()
{
#if 0
for(NodeEntryListList::iterator ll_it=node_list_list_->begin();ll_it!=node_list_list_->end();++ll_it) {
for(NodeEntryList::iterator it=(*ll_it).begin();it!=(*ll_it).end();++it) {
it->rad=1.0;
}
}
#endif
FlagRebuild();
}
//////////////////////////////////////////
// protected and private methods
void Entity::set_static_max_rad()
{
//TODO implement method
}
bool Entity::HasSelection() const
{
return (sel_.IsValid() && sel_.GetAtomCount()>0);
}
namespace {
template <typename I, typename O>
void apply_color_op_to_renderer_list(I begin, I end, const O& o)
{
for (I i=begin; i!=end; ++i) {
i->second->Apply(o);
}
}
}
void Entity::Apply(const gfx::UniformColorOp& op, bool store)
{
if(store){
UniformColorOp* op_ptr = new UniformColorOp(op);
this->AppendColorOp(op_ptr);
}
apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
FlagRebuild();
}
void Entity::Apply(const gfx::GradientLevelColorOp& op, bool store)
{
if(store){
GradientLevelColorOp* op_ptr = new GradientLevelColorOp(op);
this->AppendColorOp(op_ptr);
}
if(op.GetCalculateMinMax()){
std::pair<float,float> minmax = this->GetView().GetMinMax(op.GetProperty(), op.GetLevel());
op.SetMinV(minmax.first);
op.SetMaxV(minmax.second);
}
apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
FlagRebuild();
}
void Entity::Apply(const gfx::ByElementColorOp& op, bool store)
{
if(store){
ByElementColorOp* op_ptr = new ByElementColorOp(op);
this->AppendColorOp(op_ptr);
}
apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
FlagRebuild();
}
void Entity::Apply(const gfx::EntityViewColorOp& op, bool store)
{
if(store){
EntityViewColorOp* op_ptr = new EntityViewColorOp(op);
this->AppendColorOp(op_ptr);
}
apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
FlagRebuild();
}
#if OST_IMG_ENABLED
void Entity::Apply(const gfx::MapHandleColorOp& op, bool store)
{
if(store){
MapHandleColorOp* op_ptr = new MapHandleColorOp(op);
this->AppendColorOp(op_ptr);
}
apply_color_op_to_renderer_list(renderer_.begin(), renderer_.end(), op);
FlagRebuild();
}
#endif
void Entity::CleanColorOps()
{
GfxObj::CleanColorOps();
}
void Entity::ReapplyColorOps()
{
GfxObj::ReapplyColorOps();
}
}} // ns