COPASI API  4.16.103
Public Member Functions | Static Public Member Functions | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
CLLayoutRenderer Class Reference

#include <CLLayoutRenderer.h>

Collaboration diagram for CLLayoutRenderer:
Collaboration graph
[legend]

Public Member Functions

void addToSelection (CLGraphicalObject *pObject)
 
void analyse_render_information (double lx, double ly, double rx, double ry)
 
void change_style (const CLGlobalRenderInformation *pRenderInformation, bool defaultStyle=false)
 
void change_style (const CLLocalRenderInformation *pRenderInformation)
 
void clearSelection ()
 
 CLLayoutRenderer (CLayout *pLayout, const CLGlobalRenderInformation *pRenderInformation, const CCopasiVector< CLGlobalRenderInformation > *pGlobalRenderInformationList, const CModel *pModel, const std::string &baseDir)
 
 CLLayoutRenderer (CLayout *pLayout, const CLLocalRenderInformation *pRenderInformation, const CCopasiVector< CLGlobalRenderInformation > *pGlobalRenderInformationList, const CModel *pModel, const std::string &baseDir)
 
std::pair< double, double > convert_to_model_space (double x, double y) const
 
void draw_layout ()
 
double getAspect () const
 
const GLfloat * getFogColor () const
 
GLfloat getFogDensity () const
 
const GLfloat * getHighlightColor () const
 
const std::set< const
CLGraphicalObject * > & 
getHighlightedObjects () const
 
std::set< const
CLGraphicalObject * > & 
getHighlightedObjects ()
 
bool getHighlightFlag () const
 
std::multiset
< CLGraphicalObject
*, compareGraphicalObjectsBySize
getObjectsAt (double x, double y)
 
std::multiset
< CLGraphicalObject
*, compareGraphicalObjectsBySize
getObjectsAtViewportPosition (unsigned int x, unsigned int y)
 
std::vector< CLGraphicalObject * > getObjectsInBoundingBox (double lx, double ly, double rx, double ry, bool partial=true)
 
std::set< CLGraphicalObject * > & getSelection ()
 
const std::set
< CLGraphicalObject * > & 
getSelection () const
 
CLBoundingBoxgetSelectionBox ()
 
const CLBoundingBoxgetSelectionBox () const
 
double getZoomFactor () const
 
bool isSelected (const CLGraphicalObject *) const
 
bool isSetDeduceSpeciesReferenceRoles () const
 
void move_curve_object (CLCurve *pCurve, double dx, double dy, bool leaveStartPoint=false, bool leaveEndpoint=false)
 
void move_graphical_object (CLGraphicalObject *pObject, double dx, double dy)
 
void move_reaction_glyph (CLReactionGlyph *pRG, double dx, double dy, bool moveSelectedAssociation=false)
 
void move_selection (double dx, double dy, bool moveAssociated=true)
 
void move_species_glyph (CLMetabGlyph *pSG, double dx, double dy, bool moveSelectedAssociations=false)
 
void move_species_reference_glyph (CLMetabReferenceGlyph *pSRG, double dx, double dy)
 
void move_text_glyph (CLTextGlyph *pTG, double dx, double dy)
 
void removeFromSelection (CLGraphicalObject *pObject)
 
void resize (GLsizei w, GLsizei h)
 
void set_font_renderer (CLFontRendererBase *pFontRenderer)
 
void setAspect (double aspect)
 
void setDeduceSpeciesReferenceRoles (bool deduce)
 
void setFogColor (const GLfloat c[4])
 
void setFogDensity (GLfloat dens)
 
void setHighlightColor (const GLfloat c[4])
 
void setHighlightedObjects (const std::set< const CLGraphicalObject * > &highlightedObjects)
 
void setHighlightFlag (bool flag)
 
void setImageTexturizer (CLImageTexturizer *pTexturizer)
 
void setSelectionBox (const CLBoundingBox *pBox)
 
void setX (double x)
 
void setY (double y)
 
void setZoomFactor (double zoomFactor)
 
void toggleHighlightFlag ()
 
 ~CLLayoutRenderer ()
 

Static Public Member Functions

static double distance (const CLPoint &p1, const CLPoint &p2)
 
static CLBoundingBoxgetCurveBoundingBox (const CLCurve *pCurve)
 
static bool is_curve_segment_visible (const CLLineSegment &segment, double lx, double ly, double rx, double ry, bool partial)
 
static bool is_curve_visible (const CLCurve &curve, double lx, double ly, double rx, double ry, bool partial)
 
static CLCurverevert_curve (const CLCurve *pCurve)
 

Protected Member Functions

void clear_cached_data ()
 
void create_gradient_texture (unsigned int size, GLubyte *pData, const CLGradientBase *pGradient, double z_value=0.0)
 
void create_linear_gradient_texture (unsigned int size, GLubyte *pData, const CLLinearGradient *pGradient, double z_value)
 
void create_radial_gradient_texture (unsigned int size, GLubyte *pData, const CLRadialGradient *pGradient, double z_value)
 
void draw_cap (double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double stroke_width)
 
void draw_curve (const CLCurve *pCurve, bool drawBasepoints=false)
 
void draw_curve (const CLRenderCurve *pCurve, const CLBoundingBox *pBB)
 
void draw_datapoints (GLdouble *pData, size_t numPoints, const CLBoundingBox *pBB, bool doTesselation=false, float xOffset=0.0, float yOffset=0.0, float zOffset=0.0)
 
void draw_ellipse (const CLEllipse *pEllipse, const CLBoundingBox *pBB)
 
void draw_group (const CLGroup *pGroup, const CLBoundingBox *pBB)
 
void draw_image (const CLImage *pImage, const CLBoundingBox *pBB)
 
void draw_line (size_t numPoints, GLdouble *pData)
 
void draw_line_segment (double x1, double y1, double z1, double x2, double y2, double z2, double line_width, bool texture=false, double s1=0.0, double s2=0.0)
 
void draw_object (const CLStyle *pStyle, const CLBoundingBox *pBB)
 
void draw_polygon (const CLPolygon *pPolygon, const CLBoundingBox *pBB)
 
void draw_rectangle (const CLRectangle *pRectangle, const CLBoundingBox *pBB)
 
void draw_selection_box () const
 
void draw_text (const CLStyle *pStyle, const CLBoundingBox *pBB, const CLTextTextureSpec *pTexture)
 
void draw_text (const CLText *pText, const CLBoundingBox *pBB)
 
void draw_text (const CLTextTextureSpec *pTexture, double x, double y, double z, const CLBoundingBox *pBB)
 
void initialize_gl_extension_functions ()
 
void map_arrow_head (const CLPoint &p, const CLPoint &v, const std::string &headId)
 
void map_gradient_color (double rel_distance, const CLGradientBase *pGradient, GLubyte *pData)
 
void resolve_color (const std::string &color, GLubyte array[4])
 
void restore_current_attributes ()
 
void save_current_attributes ()
 
void segment_data (double length, double ratio, size_t numPoints, GLdouble *pData, std::vector< simple_point > &v)
 
void update_associations ()
 
void update_colors (const CLGradientBase *pGradient)
 
void update_drawables (double lx, double ly, double rx, double ry)
 
void update_style_information ()
 
void update_textures_and_colors ()
 
void update_textures_and_colors (const CLGroup *pGroup, double maxDimension, double height, const std::string &parentFill="", CLFontSpec parentFontSpec=CLFontSpec())
 

Static Protected Member Functions

static void calculate_cubicbezier (double sx, double sy, double sz, double p1x, double p1y, double p1z, double p2x, double p2y, double p2z, double ex, double ey, double ez, unsigned int numPoints, GLdouble *pData)
 
static CLPointcalculate_intersection (double p1x, double p1y, double p1z, double sx, double sy, double sz, double p2x, double p2y, double p2z, double tx, double ty, double tz)
 
static std::pair< double, double > calculate_intersection_point_2d (double p1x, double p1y, double sx, double sy, double p2x, double p2y, double tx, double ty)
 
static void COMBINE_CALLBACK (GLdouble coords[3], GLdouble **, GLfloat *, GLdouble **dataOut)
 
static void COMBINE_CALLBACK_GRADIENT (GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
 
static const CLPoint convert_to_absolute (const CLRenderPoint *pRenderPoint, const CLBoundingBox *pBB)
 
static void createGLMatrix (const double *const matrix, GLdouble *glMatrix)
 
static CLLineStippleTexturecreateLineStippleTexture (const std::vector< unsigned int > &dasharray)
 
static double distancePointLineSegment (double x, double y, double lx1, double ly1, double lx2, double ly2)
 
static void drawSelectionBox (double x, double y, double width, double height, bool drawHandles=false)
 
static void extract_1d_attributes (const CLGraphicalPrimitive1D *pObject, CLGroupAttributes *attributes)
 
static void extract_2d_attributes (const CLGraphicalPrimitive2D *pObject, CLGroupAttributes *attributes)
 
template<typename T >
static void extract_arrowhead_information (const T *pObject, CLGroupAttributes *attributes)
 
static void extract_group_attributes (const CLStyle *pStyle, CLGroupAttributes *attributes)
 
static void extract_group_attributes (const CLGroup *pGroup, CLGroupAttributes *attributes)
 
template<typename T >
static void extract_text_attributes (const T *pObject, CLGroupAttributes *attributes)
 
static void extract_transformation_attributes (const CLTransformation *pObject, CLGroupAttributes *attributes)
 
static CLFontSpec getFontSpec (const CLGroup *pGroup, double boxHeight, const CLFontSpec &parentFontSpec=CLFontSpec())
 
static CLFontSpec getFontSpec (const CLText *pText, double boxHeight, const CLFontSpec &parentFontSpec=CLFontSpec())
 
static bool isSegmentHit (const CLLineSegment *pLS, double x, double y, double toleranceRadius)
 
static const std::string resolve_text (const CLTextGlyph *pTextGlyph)
 
static bool segments_intersect_2d (double p1x1, double p1y1, double p1x2, double p1y2, double p2x1, double p2y1, double p2x2, double p2y2)
 
static void TESS_ERROR (GLenum error)
 
static void VERTEX_CALLBACK_GRADIENT (GLvoid *vertex)
 

Protected Attributes

double mAspect
 
std::string mBaseDir
 
std::map< std::string,
CLRGBAColor
mColorMap
 
CLGroupAttributes mCurrentAttributes
 
bool mDeduceSpeciesReferenceRoles
 
std::vector< const
CLGraphicalObject * > 
mDrawables
 
GLfloat mFogColor [4]
 
GLfloat mFogDensity
 
std::map< CLFontSpec, std::map
< std::string,
CLTextTextureSpec * > > 
mFontTextureMap
 
bool mGLFunctionsInitialized
 
std::map< std::string,
std::pair< const
CLGradientBase
*, CLTextureSpec * > > 
mGradientMap
 
std::map< CLGraphicalObject
*, std::set< CLTextGlyph * > > 
mGraphicalObjectToTextGlyphMap
 
double mH
 
bool mHighlight
 
GLfloat mHighlightColor [4]
 
std::set< const
CLGraphicalObject * > 
mHighlightedObjects
 
std::map< std::string, const
CLTextureSpec * > 
mImageMap
 
std::map< std::string, const
CLLineEnding * > 
mLineEndingMap
 
std::map< const std::vector
< unsigned int >, const
CLLineStippleTexture * > 
mLinestippleMap
 
CLFontRendererBasempFontRenderer
 
void(* mpGlFogCoordfEXT )(GLfloat)
 
const CCopasiVector
< CLGlobalRenderInformation > * 
mpGlobalRenderInfoList
 
CLImageTexturizermpImageTexturizer
 
CLayoutmpLayout
 
const CModelmpModel
 
CLRenderResolvermpResolver
 
CLBoundingBoxmpSelectionBox
 
std::map< CLReactionGlyph
*, std::set< std::pair
< CLMetabReferenceGlyph
*, bool > > > 
mReactionToSpeciesReferenceMap
 
std::set< CLGraphicalObject * > mSelection
 
std::map< const
CLMetabReferenceGlyph
*, std::string > 
mSpeciesReferencesWithDeducedRole
 
std::map
< CLMetabReferenceGlyph
*, std::pair< CLReactionGlyph
*, bool > > 
mSpeciesReferenceToReactionMap
 
std::map
< CLMetabReferenceGlyph
*, std::pair< CLMetabGlyph
*, bool > > 
mSpeciesReferenceToSpeciesMap
 
std::map< CLMetabGlyph
*, std::set< std::pair
< CLMetabReferenceGlyph
*, bool > > > 
mSpeciesToSpeciesReferenceMap
 
std::stack< CLGroupAttributesmStateList
 
std::map< const
CLGraphicalObject *, const
CLStyle * > 
mStyleMap
 
std::map< const CLTextGlyph
*, const CLTextTextureSpec * > 
mTextGlyphMap
 
std::map< CLTextGlyph
*, CLGraphicalObject * > 
mTextGlyphToGraphicalObjectMap
 
std::map< const CLText
*, const CLTextTextureSpec * > 
mTextMap
 
std::set< GLuint > mTextureNames
 
double mW
 
double mX
 
double mY
 
double mZoomFactor
 

Static Protected Attributes

static const double ALMOST_ZERO = 1e-12
 
static const unsigned int GRADIENT_TEXTURE_SIZE_LIMIT = 512
 
static const unsigned int NUM_BEZIER_POINTS = 20
 
static const unsigned int NUM_CIRCLE_SEGMENTS = 60
 
static const unsigned int NUM_CORNER_SEGMENTS = 10
 
static const double SELECTION_FRAME_WIDTH = 3.0
 

Detailed Description

Definition at line 61 of file CLLayoutRenderer.h.

Constructor & Destructor Documentation

CLLayoutRenderer::CLLayoutRenderer ( CLayout pLayout,
const CLGlobalRenderInformation pRenderInformation,
const CCopasiVector< CLGlobalRenderInformation > *  pGlobalRenderInformationList,
const CModel pModel,
const std::string &  baseDir 
)

constructor for global render information

Definition at line 103 of file CLLayoutRenderer.cpp.

References change_style(), mFogColor, and mHighlightColor.

103  :
104  mStateList(),
106  mpModel(pModel),
107  mpLayout(pLayout),
108  mpResolver(NULL),
109  mBaseDir(baseDir),
110  mZoomFactor(1.0),
111  mAspect(1.0),
112  mX(0.0),
113  mY(0.0),
114  mW(0.0),
115  mH(0.0),
116  mpGlobalRenderInfoList(pGlobalRenderInformationList),
117  mpFontRenderer(NULL),
119  mpSelectionBox(NULL),
120  mpImageTexturizer(NULL)
121  , mHighlight(true)
122  , mFogDensity(0.8f)
123  , mGLFunctionsInitialized(false)
124  , mpGlFogCoordfEXT(NULL)
125 {
126  this->mHighlightColor[0] = 0.5;
127  this->mHighlightColor[1] = 0.0;
128  this->mHighlightColor[2] = 0.0;
129  this->mHighlightColor[3] = 1.0;
130  this->mFogColor[0] = 0.5;
131  this->mFogColor[1] = 0.5;
132  this->mFogColor[2] = 0.5;
133  this->mFogColor[3] = 1.0;
134  this->change_style(pRenderInformation);
135 }
CLBoundingBox * mpSelectionBox
GLfloat mHighlightColor[4]
std::stack< CLGroupAttributes > mStateList
CLImageTexturizer * mpImageTexturizer
CLGroupAttributes mCurrentAttributes
const CCopasiVector< CLGlobalRenderInformation > * mpGlobalRenderInfoList
std::string mBaseDir
void change_style(const CLGlobalRenderInformation *pRenderInformation, bool defaultStyle=false)
CLFontRendererBase * mpFontRenderer
void(* mpGlFogCoordfEXT)(GLfloat)
CLRenderResolver * mpResolver
const CModel * mpModel
CLLayoutRenderer::CLLayoutRenderer ( CLayout pLayout,
const CLLocalRenderInformation pRenderInformation,
const CCopasiVector< CLGlobalRenderInformation > *  pGlobalRenderInformationList,
const CModel pModel,
const std::string &  baseDir 
)

constructor for local render information

Definition at line 140 of file CLLayoutRenderer.cpp.

References change_style(), initialize_gl_extension_functions(), mFogColor, and mHighlightColor.

140  :
141  mStateList(),
143  mpModel(pModel),
144  mpLayout(pLayout),
145  mpResolver(NULL),
146  mBaseDir(baseDir),
147  mZoomFactor(1.0),
148  mAspect(1.0),
149  mX(0.0),
150  mY(0.0),
151  mW(0.0),
152  mH(0.0),
153  mpGlobalRenderInfoList(pGlobalRenderInformationList),
154  mpFontRenderer(NULL),
156  mpSelectionBox(NULL)
157  , mHighlight(true)
158  , mFogDensity(0.8f)
159  , mGLFunctionsInitialized(false)
160  , mpGlFogCoordfEXT(NULL)
161 {
162  this->mHighlightColor[0] = 0.5;
163  this->mHighlightColor[1] = 0.0;
164  this->mHighlightColor[2] = 0.0;
165  this->mHighlightColor[3] = 1.0;
166  this->mFogColor[0] = 0.5;
167  this->mFogColor[1] = 0.5;
168  this->mFogColor[2] = 0.5;
169  this->mFogColor[3] = 1.0;
171  this->change_style(pRenderInformation);
172 }
CLBoundingBox * mpSelectionBox
GLfloat mHighlightColor[4]
std::stack< CLGroupAttributes > mStateList
CLGroupAttributes mCurrentAttributes
const CCopasiVector< CLGlobalRenderInformation > * mpGlobalRenderInfoList
std::string mBaseDir
void change_style(const CLGlobalRenderInformation *pRenderInformation, bool defaultStyle=false)
CLFontRendererBase * mpFontRenderer
void(* mpGlFogCoordfEXT)(GLfloat)
void initialize_gl_extension_functions()
CLRenderResolver * mpResolver
const CModel * mpModel
CLLayoutRenderer::~CLLayoutRenderer ( )

destructor.

Definition at line 234 of file CLLayoutRenderer.cpp.

References clear_cached_data(), mpFontRenderer, mpResolver, and mpSelectionBox.

235 {
236  if (mpResolver != NULL) delete mpResolver;
237 
238  // delete the data in all the maps
239  this->clear_cached_data();
240 
241  if (this->mpFontRenderer)
242  {
243  delete this->mpFontRenderer;
244  }
245 
246  if (this->mpSelectionBox != NULL)
247  {
248  delete this->mpSelectionBox;
249  }
250 }
CLBoundingBox * mpSelectionBox
CLFontRendererBase * mpFontRenderer
CLRenderResolver * mpResolver

Member Function Documentation

void CLLayoutRenderer::addToSelection ( CLGraphicalObject pObject)

This method adds a graphical object to the set of selected objects.

Definition at line 4968 of file CLLayoutRenderer.cpp.

References draw_layout(), and mSelection.

Referenced by CQGLLayoutPainter::mousePressEvent(), and CQGLLayoutPainter::mouseReleaseEvent().

4969 {
4970  assert(pObject != NULL);
4971 
4972  if (this->mSelection.insert(pObject).second == true)
4973  {
4974  this->draw_layout();
4975  }
4976 }
std::set< CLGraphicalObject * > mSelection
void CLLayoutRenderer::analyse_render_information ( double  lx,
double  ly,
double  rx,
double  ry 
)

Analyses the render information and creates some of the textures. First it determines which object are drawn based on the viewport coordinates that are passed in. Next it resolves the styles for all the objects that are to be drawn and it determines the size of the textures. Last it creates all textures.

Definition at line 3310 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO, update_drawables(), update_style_information(), and update_textures_and_colors().

Referenced by change_style(), resize(), and setDeduceSpeciesReferenceRoles().

3311 {
3312  // go through the complete render information and resolve all colors
3313  // go through the list of gradients and create CLText*ureSpec objects for each
3314  // one and put it in a map
3315  // go through the complete layout and find the largest usage of any
3316  // gradient
3317  // Create the gradients
3318  // go through the layout and find all line stipple patterns and create the
3319  // textures placeholders for them
3320 
3321  // store the styles that have already been processed so that we process
3322  // each style only once
3323  if (rx - lx > ALMOST_ZERO && ry - ly > ALMOST_ZERO)
3324  {
3325  this->update_drawables(lx, ly, rx, ry);
3326  this->update_style_information();
3328  }
3329 }
static const double ALMOST_ZERO
void update_drawables(double lx, double ly, double rx, double ry)
void CLLayoutRenderer::calculate_cubicbezier ( double  sx,
double  sy,
double  sz,
double  p1x,
double  p1y,
double  p1z,
double  p2x,
double  p2y,
double  p2z,
double  ex,
double  ey,
double  ez,
unsigned int  numPoints,
GLdouble *  pData 
)
staticprotected

Calculates the points for a cubic bezier curve. The algorithm calculates numPoints and stores them in pData. pData has to be an array with enough space for numPoints*3 GLfloat items.

Definition at line 3036 of file CLLayoutRenderer.cpp.

Referenced by draw_curve(), draw_polygon(), is_curve_segment_visible(), and isSegmentHit().

3037 {
3038  unsigned int index = 0;
3039  pData[index++] = sx;
3040  pData[index++] = sy;
3041  pData[index++] = sz;
3042  unsigned int i, iMax = numPoints - 1;
3043  double stepSize = 1.0 / (float)(iMax);
3044  double t = 0.0;
3045  double t_square = 0.0;
3046  double t_cube = 0.0;
3047  double oneMinusT = 0.0;
3048  double oneMinusT_square = 0.0;
3049  double oneMinusT_cube = 0.0;
3050  double a, b;
3051 
3052  for (i = 1; i < iMax; ++i)
3053  {
3054  t = i * stepSize;
3055  oneMinusT = 1.0 - t;
3056  oneMinusT_square = oneMinusT * oneMinusT;
3057  oneMinusT_cube = oneMinusT * oneMinusT_square;
3058  t_square = t * t;;
3059  t_cube = t_square * t;
3060  a = 3 * t * oneMinusT_square;
3061  b = 3 * t_square * oneMinusT;
3062  pData[index++] = sx * oneMinusT_cube + p1x * a + p2x * b + ex * t_cube;
3063  pData[index++] = sy * oneMinusT_cube + p1y * a + p2y * b + ey * t_cube;
3064  pData[index++] = sz * oneMinusT_cube + p1z * a + p2z * b + ez * t_cube;
3065  }
3066 
3067  pData[index++] = ex;
3068  pData[index++] = ey;
3069  pData[index++] = ez;
3070 }
CLPoint * CLLayoutRenderer::calculate_intersection ( double  p1x,
double  p1y,
double  p1z,
double  sx,
double  sy,
double  sz,
double  p2x,
double  p2y,
double  p2z,
double  tx,
double  ty,
double  tz 
)
staticprotected

calculates the intersection point of two lines. The caller has to delete the returned point object.

Definition at line 4574 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO, CLPoint::getX(), CLPoint::getY(), and CLPoint::getZ().

Referenced by draw_cap().

4576 {
4577  CLPoint* pP = NULL;
4578 
4579  if (fabs(sx) > ALMOST_ZERO)
4580  {
4581  double m = (p1y - p2y + ((p2x / sx) - (p1x / sx)) * sy) / (ty - tx * sy / sx);
4582  double n = (p2x + m * tx - p1x) / sx;
4583  pP = new CLPoint(p2x + m * tx, p2y + m * ty, p2z + m * tz);
4584  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4585 
4586  if (fabs(pP->getX()) > ALMOST_ZERO)
4587  {
4588  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4589  }
4590  else
4591  {
4592  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4593  }
4594 
4595  if (fabs(pP->getY()) > ALMOST_ZERO)
4596  {
4597  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4598  }
4599  else
4600  {
4601  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4602  }
4603 
4604  if (fabs(pP->getZ()) > ALMOST_ZERO)
4605  {
4606  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4607  }
4608  else
4609  {
4610  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4611  }
4612 
4613  delete pP2;
4614  }
4615  else if (fabs(tx) > ALMOST_ZERO)
4616  {
4617  // first line is in the yz plane or a plane parallel to it
4618  // the intersection must be at p2x=p1x
4619  double m = (p1x - p2x) / tx;
4620  pP = new CLPoint(p2x + m * tx, p2y + m * ty, p2z + m * tz);
4621 
4622  if (fabs(sy) > ALMOST_ZERO)
4623  {
4624  double n = (pP->getY() - p1y) / sy;
4625  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4626 
4627  if (fabs(pP->getX()) > ALMOST_ZERO)
4628  {
4629  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4630  }
4631  else
4632  {
4633  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4634  }
4635 
4636  if (fabs(pP->getY()) > ALMOST_ZERO)
4637  {
4638  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4639  }
4640  else
4641  {
4642  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4643  }
4644 
4645  if (fabs(pP->getZ()) > ALMOST_ZERO)
4646  {
4647  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4648  }
4649  else
4650  {
4651  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4652  }
4653 
4654  delete pP2;
4655  }
4656  else if (fabs(sz) > ALMOST_ZERO)
4657  {
4658  double n = (pP->getZ() - p1z) / sz;
4659  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4660 
4661  if (fabs(pP->getX()) > ALMOST_ZERO)
4662  {
4663  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4664  }
4665  else
4666  {
4667  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4668  }
4669 
4670  if (fabs(pP->getY()) > ALMOST_ZERO)
4671  {
4672  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4673  }
4674  else
4675  {
4676  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4677  }
4678 
4679  if (fabs(pP->getZ()) > ALMOST_ZERO)
4680  {
4681  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4682  }
4683  else
4684  {
4685  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4686  }
4687 
4688  delete pP2;
4689  }
4690  }
4691  else
4692  {
4693  // both lines don't have a component in the x direction, so both must
4694  // lie in the yz plane or a plane parallel to it
4695  // there can only be an intersection if the x values are the same
4696  if (fabs(p1x - p2x) < ALMOST_ZERO)
4697  {
4698  // they are in the same plane
4699  if (fabs(sy) > ALMOST_ZERO)
4700  {
4701  double m = (p1z - p2z + (p2y / sy) * sz) / (tz - ty / sy * sz);
4702  double n = (p2y + m * ty) / sy;
4703  pP = new CLPoint(p2x + m * tx, p2y + m * ty, p2z + m * tz);
4704  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4705 
4706  if (fabs(pP->getX()) > ALMOST_ZERO)
4707  {
4708  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4709  }
4710  else
4711  {
4712  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4713  }
4714 
4715  if (fabs(pP->getY()) > ALMOST_ZERO)
4716  {
4717  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4718  }
4719  else
4720  {
4721  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4722  }
4723 
4724  if (fabs(pP->getZ()) > ALMOST_ZERO)
4725  {
4726  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4727  }
4728  else
4729  {
4730  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4731  }
4732 
4733  delete pP2;
4734  }
4735  else if (fabs(ty) > ALMOST_ZERO)
4736  {
4737  double n = (p2z - p1z + (p2y / ty) * tz) / (sz - sy / ty * tz);
4738  double m = (p1y + n * sy) / ty;
4739  pP = new CLPoint(p2x + m * tx, p2y + m * ty, p2z + m * tz);
4740  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4741 
4742  if (fabs(pP->getX()) > ALMOST_ZERO)
4743  {
4744  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4745  }
4746  else
4747  {
4748  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4749  }
4750 
4751  if (fabs(pP->getY()) > ALMOST_ZERO)
4752  {
4753  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4754  }
4755  else
4756  {
4757  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4758  }
4759 
4760  if (fabs(pP->getZ()) > ALMOST_ZERO)
4761  {
4762  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4763  }
4764  else
4765  {
4766  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4767  }
4768 
4769  delete pP2;
4770  }
4771  else if (fabs(sz) > ALMOST_ZERO)
4772  {
4773  double m = (p1y - p2y + (p2z / sz) * sy) / (ty - tz / sz * sy);
4774  double n = (p2z + m * tz) / sz;
4775  pP = new CLPoint(p2x + m * tx, p2y + m * ty, p2z + m * tz);
4776  CLPoint* pP2 = new CLPoint(p1x + n * sx, p1y + n * sy, p1z + n * sz);
4777 
4778  if (fabs(pP->getX()) > ALMOST_ZERO)
4779  {
4780  assert(fabs((pP->getX() - pP2->getX()) / pP->getX()) < 1e-6);
4781  }
4782  else
4783  {
4784  assert(fabs(pP2->getX()) < ALMOST_ZERO);
4785  }
4786 
4787  if (fabs(pP->getY()) > ALMOST_ZERO)
4788  {
4789  assert(fabs((pP->getY() - pP2->getY()) / pP->getY()) < 1e-6);
4790  }
4791  else
4792  {
4793  assert(fabs(pP2->getY()) < ALMOST_ZERO);
4794  }
4795 
4796  if (fabs(pP->getZ()) > ALMOST_ZERO)
4797  {
4798  assert(fabs((pP->getZ() - pP2->getZ()) / pP->getZ()) < 1e-6);
4799  }
4800  else
4801  {
4802  assert(fabs(pP2->getZ()) < ALMOST_ZERO);
4803  }
4804 
4805  delete pP2;
4806  }
4807  }
4808  }
4809 
4810  return pP;
4811 }
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
static const double ALMOST_ZERO
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
std::pair< double, double > CLLayoutRenderer::calculate_intersection_point_2d ( double  p1x,
double  p1y,
double  sx,
double  sy,
double  p2x,
double  p2y,
double  tx,
double  ty 
)
staticprotected

Calculates the intersection point between two lines in 2D. The intersection point is returned. If the lines are parallel, a point with two NaN values is returned. All numbers <= ALMOST_ZERO are considered to be 0.

Definition at line 4470 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO.

Referenced by segments_intersect_2d().

4471 {
4472  std::pair<double, double> result = std::pair<double, double>(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN());
4473 
4474  if (fabs(sx) <= ALMOST_ZERO)
4475  {
4476  // two options -> a) tx is also 0.0 -> parallel lines
4477  // b) intersection is at p1x,??
4478  if (fabs(tx) > ALMOST_ZERO)
4479  {
4480  result = std::pair<double, double>(p1x, (p1x - p2x) * (ty / tx) + p2y);
4481  }
4482  }
4483  else if (fabs(sy) <= ALMOST_ZERO)
4484  {
4485  // two options a) ty is also 0.0 -> parallel lines
4486  // b) intersection at ??,p1y
4487 
4488  if (fabs(tx) > ALMOST_ZERO)
4489  {
4490  if (fabs(ty) > ALMOST_ZERO)
4491  {
4492  result = std::pair<double, double>((p1y - p2y) * (tx / ty) - p2x, p1y);
4493  }
4494  }
4495  else
4496  {
4497  result = std::pair<double, double>(p2x, p1y);
4498  }
4499  }
4500  else if (fabs(tx) <= ALMOST_ZERO)
4501  {
4502  // intersection is at p2x,??
4503  if (fabs(sy) > ALMOST_ZERO)
4504  {
4505  result = std::pair<double, double>(p2x, (p2x - p1x) * (sy / sx) + p1y);
4506  }
4507  }
4508  else if (fabs(ty) <= ALMOST_ZERO)
4509  {
4510  // intersection at ??,p2y
4511  result = std::pair<double, double>((p2y - p1y) * (sx / sy) - p1x, p2y);
4512  }
4513  else
4514  {
4515  // most general case
4516  // two options a) lines are parallel
4517  // b) intersection at
4518  //
4519  // check if the lines are parallel
4520  if (fabs(fabs((sx * tx + sy * ty) / (sqrt(sx * sx + sy * sy)*sqrt(tx * tx + ty * ty))) - 1) > ALMOST_ZERO)
4521  {
4522  double ss = sy / sx;
4523  double st = ty / tx;
4524  double ys = p1y - p1x * ss;
4525  double yt = p2y - p2x * st;
4526  // if not, the intersection is at
4527  double x = (ss - st) / (yt - ys);
4528  double y = ss * x + ys;
4529  result = std::pair<double, double>(x, y);
4530  }
4531  }
4532 
4533  return result;
4534 }
static const double ALMOST_ZERO
void CLLayoutRenderer::change_style ( const CLGlobalRenderInformation pRenderInformation,
bool  defaultStyle = false 
)

This method replaces the current style with the given global render information.

Definition at line 174 of file CLLayoutRenderer.cpp.

References analyse_render_information(), clear_cached_data(), mDeduceSpeciesReferenceRoles, mH, mpFontRenderer, mpGlobalRenderInfoList, mpResolver, mSpeciesReferencesWithDeducedRole, mW, mX, mY, mZoomFactor, CLRenderResolver::setDeducedObjectRoles(), and setDeduceSpeciesReferenceRoles().

Referenced by CQGLLayoutPainter::change_style(), and CLLayoutRenderer().

175 {
176  if (this->mpResolver != NULL)
177  {
178  delete this->mpResolver;
179  this->mpResolver = NULL;
180  }
181 
182  if (pRenderInformation)
183  {
184  this->mpResolver = new CLRenderResolver(*pRenderInformation, *this->mpGlobalRenderInfoList);
185  }
186 
187  if (defaultStyle == true)
188  {
189  this->setDeduceSpeciesReferenceRoles(true);
190  }
191 
192  this->clear_cached_data();
193 
194  if (this->mpFontRenderer != NULL)
195  {
196  this->analyse_render_information(mX, mY, mX + mW / this->mZoomFactor, mY + mH / this->mZoomFactor);
197  }
198 
200  {
202  }
203 }
void setDeducedObjectRoles(const std::map< const CLMetabReferenceGlyph *, std::string > &deducedObjectRoles)
const CCopasiVector< CLGlobalRenderInformation > * mpGlobalRenderInfoList
std::map< const CLMetabReferenceGlyph *, std::string > mSpeciesReferencesWithDeducedRole
CLFontRendererBase * mpFontRenderer
CLRenderResolver * mpResolver
void setDeduceSpeciesReferenceRoles(bool deduce)
void analyse_render_information(double lx, double ly, double rx, double ry)
void CLLayoutRenderer::change_style ( const CLLocalRenderInformation pRenderInformation)

This method replaces the current style with the given glocal render information.

Definition at line 205 of file CLLayoutRenderer.cpp.

References analyse_render_information(), clear_cached_data(), CLayout::getListOfLocalRenderInformationObjects(), mDeduceSpeciesReferenceRoles, mH, mpFontRenderer, mpGlobalRenderInfoList, mpLayout, mpResolver, mSpeciesReferencesWithDeducedRole, mW, mX, mY, mZoomFactor, and CLRenderResolver::setDeducedObjectRoles().

206 {
207  if (this->mpResolver != NULL)
208  {
209  delete this->mpResolver;
210  this->mpResolver = NULL;
211  }
212 
213  if (pRenderInformation)
214  {
215  this->mpResolver = new CLRenderResolver(*pRenderInformation, this->mpLayout->getListOfLocalRenderInformationObjects(), *this->mpGlobalRenderInfoList);
216  }
217 
218  this->clear_cached_data();
219 
220  if (this->mpFontRenderer != NULL)
221  {
222  this->analyse_render_information(mX, mY, mX + mW / this->mZoomFactor, mY + mH / this->mZoomFactor);
223  }
224 
226  {
228  }
229 }
const CCopasiVector< CLLocalRenderInformation > & getListOfLocalRenderInformationObjects() const
Definition: CLayout.h:149
void setDeducedObjectRoles(const std::map< const CLMetabReferenceGlyph *, std::string > &deducedObjectRoles)
const CCopasiVector< CLGlobalRenderInformation > * mpGlobalRenderInfoList
std::map< const CLMetabReferenceGlyph *, std::string > mSpeciesReferencesWithDeducedRole
CLFontRendererBase * mpFontRenderer
CLRenderResolver * mpResolver
void analyse_render_information(double lx, double ly, double rx, double ry)
void CLLayoutRenderer::clear_cached_data ( )
protected

Removes all entries from all cache maps and frees the memory for the textures.

Definition at line 4378 of file CLLayoutRenderer.cpp.

References mColorMap, mDrawables, mFontTextureMap, mGradientMap, mImageMap, mLineEndingMap, mLinestippleMap, mStyleMap, mTextGlyphMap, and mTextMap.

Referenced by change_style(), setDeduceSpeciesReferenceRoles(), and ~CLLayoutRenderer().

4379 {
4380  std::map<std::string, std::pair<const CLGradientBase*, CLTextureSpec*> >::iterator it1 = this->mGradientMap.begin(), endit1 = this->mGradientMap.end();
4381 
4382  while (it1 != endit1)
4383  {
4384  if (it1->second.second != NULL)
4385  {
4386  if (it1->second.second->mTextureName != 0)
4387  {
4388  glDeleteTextures(1, &it1->second.second->mTextureName);
4389  }
4390 
4391  delete it1->second.second;
4392  }
4393 
4394  ++it1;
4395  }
4396 
4397  this->mGradientMap.clear();
4398  std::map<CLFontSpec, std::map<std::string, CLTextTextureSpec*> >::iterator it2 = this->mFontTextureMap.begin(), endit2 = this->mFontTextureMap.end();
4399 
4400  while (it2 != endit2)
4401  {
4402  std::map<std::string, CLTextTextureSpec*>::const_iterator it3 = it2->second.begin(), endit3 = it2->second.end();
4403 
4404  while (it3 != endit3)
4405  {
4406  if (it3->second != NULL)
4407  {
4408  if (it3->second->mTextureName != 0)
4409  {
4410  glDeleteTextures(1, &it3->second->mTextureName);
4411  }
4412 
4413  delete it3->second;
4414  }
4415 
4416  ++it3;
4417  }
4418 
4419  it2->second.clear();
4420  ++it2;
4421  }
4422 
4423  this->mFontTextureMap.clear();
4424  std::map<const std::vector<unsigned int>, const CLLineStippleTexture*>::const_iterator it3 = this->mLinestippleMap.begin(), endit3 = this->mLinestippleMap.end();
4425 
4426  while (it3 != endit3)
4427  {
4428  if (it3->second != NULL)
4429  {
4430  delete it3->second;
4431  }
4432 
4433  ++it3;
4434  }
4435 
4436  this->mLinestippleMap.clear();
4437  // delete all image textures
4438  std::map<std::string, const CLTextureSpec*>::iterator it4 = this->mImageMap.begin(), endit4 = this->mImageMap.end();
4439 
4440  while (it4 != endit4)
4441  {
4442  if (it4->second != NULL)
4443  {
4444  if (it4->second->mTextureName != 0)
4445  {
4446  glDeleteTextures(1, &it4->second->mTextureName);
4447  }
4448 
4449  delete it4->second;
4450  }
4451 
4452  ++it4;
4453  }
4454 
4455  this->mImageMap.clear();
4456  this->mColorMap.clear();
4457  this->mStyleMap.clear();
4458  this->mDrawables.clear();
4459  this->mLineEndingMap.clear();
4460  this->mTextGlyphMap.clear();
4461  this->mTextMap.clear();
4462 }
std::map< const CLText *, const CLTextTextureSpec * > mTextMap
std::vector< const CLGraphicalObject * > mDrawables
std::map< const CLTextGlyph *, const CLTextTextureSpec * > mTextGlyphMap
std::map< std::string, std::pair< const CLGradientBase *, CLTextureSpec * > > mGradientMap
std::map< std::string, const CLTextureSpec * > mImageMap
std::map< const std::vector< unsigned int >, const CLLineStippleTexture * > mLinestippleMap
std::map< std::string, CLRGBAColor > mColorMap
std::map< std::string, const CLLineEnding * > mLineEndingMap
std::map< CLFontSpec, std::map< std::string, CLTextTextureSpec * > > mFontTextureMap
std::map< const CLGraphicalObject *, const CLStyle * > mStyleMap
void CLLayoutRenderer::clearSelection ( )

This method clears the selection.

Definition at line 5020 of file CLLayoutRenderer.cpp.

References mSelection.

Referenced by CQGLLayoutPainter::mousePressEvent(), and CQGLLayoutPainter::mouseReleaseEvent().

5021 {
5022  if (!this->mSelection.empty())
5023  {
5024  this->mSelection.clear();
5025  }
5026 }
std::set< CLGraphicalObject * > mSelection
void CLLayoutRenderer::COMBINE_CALLBACK ( GLdouble  coords[3],
GLdouble **  ,
GLfloat *  ,
GLdouble **  dataOut 
)
staticprotected

This static method is used as a callback for the GLU tesselator. It is needed for polygons that intersect which itself and the tesselator has to create a new vertex at the intersection.

Definition at line 2983 of file CLLayoutRenderer.cpp.

Referenced by draw_datapoints().

2984 {
2985  GLdouble* vertex;
2986  //int i;
2987  vertex = new GLdouble[3];
2988  vertex[0] = coords[0];
2989  vertex[1] = coords[1];
2990  vertex[2] = coords[2];
2991  *dataOut = vertex;
2992 }
void CLLayoutRenderer::COMBINE_CALLBACK_GRADIENT ( GLdouble  coords[3],
GLdouble *  vertex_data[4],
GLfloat  weight[4],
GLdouble **  dataOut 
)
staticprotected

This static method is used as a callback for the GLU tesselator. It is needed for polygons that intersect which itself and the tesselator has to create a new vertex at the intersection.

Definition at line 2994 of file CLLayoutRenderer.cpp.

Referenced by draw_datapoints().

2995 {
2996  GLdouble* vertex;
2997  vertex = new GLdouble[5];
2998  vertex[0] = coords[0];
2999  vertex[1] = coords[1];
3000  vertex[2] = coords[2];
3001  vertex[3] = weight[0] * vertex_data[0][3]
3002  + weight[1] * vertex_data[1][3]
3003  + weight[2] * vertex_data[2][3]
3004  + weight[3] * vertex_data[3][3];
3005  vertex[4] = weight[0] * vertex_data[0][4]
3006  + weight[1] * vertex_data[1][4]
3007  + weight[2] * vertex_data[2][4]
3008  + weight[3] * vertex_data[3][4];
3009  *dataOut = vertex;
3010 }
const CLPoint CLLayoutRenderer::convert_to_absolute ( const CLRenderPoint pRenderPoint,
const CLBoundingBox pBB 
)
staticprotected

Converts a given RenderPoint which can have relative values into a layout Point with only absolute values.

Converts a given CLRenderPoint which can have relative values into a layout CLPoint with only absolute values. Even the absolute values of the point which are relative to the bounding box are translated into absolute coordinates.

Definition at line 924 of file CLLayoutRenderer.cpp.

References CLRelAbsVector::getAbsoluteValue(), CLDimensions::getDepth(), CLBoundingBox::getDimensions(), CLDimensions::getHeight(), CLBoundingBox::getPosition(), CLRelAbsVector::getRelativeValue(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), CLRenderPoint::x(), CLRenderPoint::y(), and CLRenderPoint::z().

Referenced by draw_curve(), draw_image(), draw_polygon(), and draw_rectangle().

925 {
926  const CLRelAbsVector& x = pRenderPoint->x();
927  const CLRelAbsVector& y = pRenderPoint->y();
928  const CLRelAbsVector& z = pRenderPoint->z();
929  const CLPoint* pPosition = &pBB->getPosition();
930  const CLDimensions* pDimensions = &pBB->getDimensions();
931  return CLPoint((x.getAbsoluteValue() + pDimensions->getWidth() * x.getRelativeValue() / 100.0) + pPosition->getX(),
932  (y.getAbsoluteValue() + pDimensions->getHeight() * y.getRelativeValue() / 100.0) + pPosition->getY(),
933  (z.getAbsoluteValue() + pDimensions->getDepth() * z.getRelativeValue() / 100.0) + pPosition->getZ());
934 }
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const C_FLOAT64 & getDepth() const
Definition: CLBase.h:213
const CLRelAbsVector & z() const
double getRelativeValue() const
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const CLRelAbsVector & y() const
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
const CLPoint & getPosition() const
Definition: CLBase.h:265
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
double getAbsoluteValue() const
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
const CLRelAbsVector & x() const
std::pair< double, double > CLLayoutRenderer::convert_to_model_space ( double  x,
double  y 
) const

converts the given coordinates from viewport space into model space.

Definition at line 6575 of file CLLayoutRenderer.cpp.

References mX, mY, and mZoomFactor.

Referenced by getObjectsAtViewportPosition(), CQGLLayoutPainter::mouseMoveEvent(), CQGLLayoutPainter::mouseReleaseEvent(), and CQGLLayoutPainter::update_status_and_cursor().

6576 {
6577  double modelX = this->mX + (double)x / this->mZoomFactor;
6578  double modelY = this->mY + (double)y / this->mZoomFactor;
6579  return std::pair<double, double>(modelX, modelY);
6580 }
void CLLayoutRenderer::create_gradient_texture ( unsigned int  size,
GLubyte *  pData,
const CLGradientBase pGradient,
double  z_value = 0.0 
)
protected

This method calculates a texture for a given gradient definition and a given size. The data object has to be a vector that can store RGBA values for a rectangle of the given size. The memory has to be allocated before calling the method. The scale specifies by how much the original box has been scaled.

Definition at line 2139 of file CLLayoutRenderer.cpp.

References create_linear_gradient_texture(), and create_radial_gradient_texture().

Referenced by update_textures_and_colors().

2140 {
2141  if (pGradient)
2142  {
2143  const CLLinearGradient* pLG = dynamic_cast<const CLLinearGradient*>(pGradient);
2144 
2145  if (pLG != NULL)
2146  {
2147  CLLayoutRenderer::create_linear_gradient_texture(size, pData, pLG, z_value);
2148  }
2149  else
2150  {
2151  const CLRadialGradient* pRG = dynamic_cast<const CLRadialGradient*>(pGradient);
2152 
2153  if (pRG != NULL)
2154  {
2155  CLLayoutRenderer::create_radial_gradient_texture(size, pData, pRG, z_value);
2156  }
2157  else
2158  {
2159  throw 0;
2160  }
2161  }
2162  }
2163 }
void create_radial_gradient_texture(unsigned int size, GLubyte *pData, const CLRadialGradient *pGradient, double z_value)
void create_linear_gradient_texture(unsigned int size, GLubyte *pData, const CLLinearGradient *pGradient, double z_value)
void CLLayoutRenderer::create_linear_gradient_texture ( unsigned int  size,
GLubyte *  pData,
const CLLinearGradient pGradient,
double  z_value 
)
protected

This method calculates a texture for a given linear gradient definition and a given size. The data object has to be a vector that can store RGBA values for a rectangle of the given size. The memory has to be allocated before calling the method. The scale specifies by how much the original box has been scaled.

Definition at line 2172 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO, CLGradientStops::color(), CLRelAbsVector::getAbsoluteValue(), CLRelAbsVector::getRelativeValue(), CLLinearGradient::getXPoint1(), CLLinearGradient::getXPoint2(), CLLinearGradient::getYPoint1(), CLLinearGradient::getYPoint2(), CLLinearGradient::getZPoint1(), CLLinearGradient::getZPoint2(), CLRGBAColor::mA, CLRGBAColor::mB, mColorMap, CLRGBAColor::mG, CLRGBAColor::mR, mZoomFactor, and CLGradientStops::update_color().

Referenced by create_gradient_texture().

2173 {
2174  // first calculate the gradient vector
2175  // we need to consider the scale
2176  CLGradientStops stops(pGradient, this->mColorMap);
2177  double x1 = pGradient->getXPoint1().getAbsoluteValue() * this->mZoomFactor + (pGradient->getXPoint1().getRelativeValue() / 100.0 * size);
2178  double y1 = pGradient->getYPoint1().getAbsoluteValue() * this->mZoomFactor + (pGradient->getYPoint1().getRelativeValue() / 100.0 * size);
2179  double z1 = pGradient->getZPoint1().getAbsoluteValue() * this->mZoomFactor + (pGradient->getZPoint1().getRelativeValue() / 100.0 * 0.0);
2180  double x2 = pGradient->getXPoint2().getAbsoluteValue() * this->mZoomFactor + (pGradient->getXPoint2().getRelativeValue() / 100.0 * size);
2181  double y2 = pGradient->getYPoint2().getAbsoluteValue() * this->mZoomFactor + (pGradient->getYPoint2().getRelativeValue() / 100.0 * size);
2182  double z2 = pGradient->getZPoint2().getAbsoluteValue() * this->mZoomFactor + (pGradient->getZPoint2().getRelativeValue() / 100.0 * 0.0);
2183  // for each point we need to calculate the distance from p1 along the
2184  // vector v(p1,p2)
2185  // first we need the plane that is perpendicular to the vector v(p1,p2)
2186  // the we need to calculate the distance of a plane from that range of
2187  // planes to p1 and normalize it with the length of v(p1,p2)
2188  // the distance can be positive or negative, this makes a difference for
2189  // the gradient calculation
2190 
2191  // rel_distance is the distance with respect to the original gradient vector
2192  // that is, a value of 1.0 means that the point is exactly as far from the
2193  // plane as the gradient vector is long
2194  double deltax = x2 - x1;
2195  double deltay = y2 - y1;
2196  double deltaz = z2 - z1;
2197  double length = sqrt(deltax * deltax + deltay * deltay + deltaz * deltaz);
2198 
2199  // line through x1,y1 that is perpendicular to v(p1,p2)
2200  if (fabs(deltax) < ALMOST_ZERO)
2201  {
2202  // the gradient is along the y axis
2203  unsigned int i, j, iMax = size, jMax = size;
2204  double rel_distance = 0.0;
2205  unsigned int index = 0;
2206 
2207  for (i = 0; i < iMax; ++i)
2208  {
2209  for (j = 0; j < jMax; ++j)
2210  {
2211  rel_distance = (double)(i - y1) / length;
2212  stops.update_color(rel_distance);
2213  pData[index] = stops.color().mR;
2214  pData[++index] = stops.color().mG;
2215  pData[++index] = stops.color().mB;
2216  pData[++index] = stops.color().mA;
2217  ++index;
2218  }
2219  }
2220  }
2221  else if (fabs(deltay) < ALMOST_ZERO)
2222  {
2223  // the gradient is along the x axis
2224  unsigned int i, j, iMax = size, jMax = size;
2225  double rel_distance = 0.0;
2226  unsigned int index = 0;
2227 
2228  for (i = 0; i < iMax; ++i)
2229  {
2230  for (j = 0; j < jMax; ++j)
2231  {
2232  rel_distance = (double)(j - x1) / length;
2233  stops.update_color(rel_distance);
2234  pData[index] = stops.color().mR;
2235  pData[++index] = stops.color().mG;
2236  pData[++index] = stops.color().mB;
2237  pData[++index] = stops.color().mA;
2238  ++index;
2239  }
2240  }
2241  }
2242  else
2243  {
2244  double slope = deltay / deltax;
2245  double inv_slope = -deltax / deltay;
2246  double c_inv = y1 - inv_slope * x1;
2247  double c;
2248  // y=s*x+c;
2249  // intersection of line
2250  unsigned int i, j, iMax = size, jMax = size;
2251  double rel_distance = 0.0;
2252  double px, py;
2253  double r = inv_slope - slope;
2254  unsigned int index = 0;
2255 
2256  for (i = 0; i < iMax; ++i)
2257  {
2258  for (j = 0; j < jMax; ++j)
2259  {
2260  c = i - slope * j;
2261  // x*slope+c=x*inv_slope+inv_c
2262  // x*slope-x*inv_slope=inv_c-c
2263  // x= (inv_c-c)/(slope-inv_slope)
2264  px = (c - c_inv) / r;
2265  py = slope * px + c;
2266  rel_distance = sqrt((j - px) * (j - px) + (i - py) * (i - py)) / length;
2267 
2268  // check if the distance is actually negative
2269  if ((j - px)*deltax + (i - py)*deltay <= 0)
2270  {
2271  rel_distance = -rel_distance;
2272  }
2273 
2274  stops.update_color(rel_distance);
2275  pData[index] = stops.color().mR;
2276  pData[++index] = stops.color().mG;
2277  pData[++index] = stops.color().mB;
2278  pData[++index] = stops.color().mA;
2279  ++index;
2280  }
2281  }
2282  }
2283 }
const CLRelAbsVector & getYPoint1() const
const CLRelAbsVector & getZPoint1() const
static const double ALMOST_ZERO
double getRelativeValue() const
const CLRelAbsVector & getXPoint2() const
std::map< std::string, CLRGBAColor > mColorMap
const CLRelAbsVector & getZPoint2() const
double getAbsoluteValue() const
const CLRelAbsVector & getYPoint2() const
const CLRelAbsVector & getXPoint1() const
void CLLayoutRenderer::create_radial_gradient_texture ( unsigned int  size,
GLubyte *  pData,
const CLRadialGradient pGradient,
double  z_value 
)
protected

This method calculates a texture for a given radial gradient definition and a given size. The data object has to be a vector that can store RGBA values for a rectangle of the given size. The memory has to be allocated before calling the method. The scale specifies by how much the original box has been scaled.

Definition at line 2292 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO, CLGradientStops::color(), CLRelAbsVector::getAbsoluteValue(), CLRadialGradient::getCenterX(), CLRadialGradient::getCenterY(), CLRadialGradient::getFocalPointX(), CLRadialGradient::getFocalPointY(), CLRadialGradient::getRadius(), CLRelAbsVector::getRelativeValue(), CLRGBAColor::mA, CLRGBAColor::mB, mColorMap, CLRGBAColor::mG, CLRGBAColor::mR, mZoomFactor, and CLGradientStops::update_color().

Referenced by create_gradient_texture().

2293 {
2294  // experiments with the focal point in firefox
2295  // - the radius seems to be aplied to the x and the y axis, so if a radius
2296  // of 50% is used in a rectangle, the circle is not a circle, but an
2297  // ellipse
2298 
2299  // spreadMethod Pad:
2300  // if the focal point is on the circle, everything that
2301  // is outside the circle and on the outside of the tangent with the circle
2302  // and the focal point is the stop color at 0%, everythin outside the
2303  // circle on the inside of the tangent is black, the color in the ellipse
2304  // depends on the distance from the focal point and the circle edge
2305  // in Inkscape this is different, everything outside the circle is the
2306  // color of the 100% stop, everything else is patterned
2307  // if the focal point is within the circle/ellipse, the whole shape has a
2308  // pattern where everything outside the circle/ellipse has the color of the
2309  // 100% stop
2310 
2311  // spreadMethod reflect:
2312  // if the focal point is on the circle, everything has the color at 0% stop
2313  // in Inkscape this is different, everything outside the tangent is the
2314  // color of the 100% stop, everything else is patterned
2315  // if the focal point is within the circle/ellipse, the whole shape has a
2316  // pattern
2317 
2318  // spreadMethod repeat:
2319  // if the focal point is on the circle, everything has the color at 0% stop
2320  // in Inkscape this is different, everything outside the tangent is the
2321  // color of the 100% stop, everything else is patterned
2322  // if the focal point is within the circle/ellipse, the whole shape has a
2323  // pattern
2324 
2325  CLGradientStops stops(pGradient, this->mColorMap);
2326  double cx = pGradient->getCenterX().getAbsoluteValue() * this->mZoomFactor + pGradient->getCenterX().getRelativeValue() / 100.0 * size;
2327  double cy = pGradient->getCenterY().getAbsoluteValue() * this->mZoomFactor + pGradient->getCenterY().getRelativeValue() / 100.0 * size;
2328  double fx = pGradient->getFocalPointX().getAbsoluteValue() * this->mZoomFactor + pGradient->getFocalPointX().getRelativeValue() / 100.0 * size;
2329  double fy = pGradient->getFocalPointY().getAbsoluteValue() * this->mZoomFactor + pGradient->getFocalPointY().getRelativeValue() / 100.0 * size;
2330  double rx = pGradient->getRadius().getAbsoluteValue() * this->mZoomFactor + pGradient->getRadius().getRelativeValue() / 100.0 * size;
2331  double ry = pGradient->getRadius().getAbsoluteValue() * this->mZoomFactor + pGradient->getRadius().getRelativeValue() / 100.0 * size;
2332  // TODO create an error if the radius is negative
2333 
2334  // TODO correct the focal point if it is outside the circle
2335 
2336  double delta_x, delta_y, slope, A, B, C, a;
2337  unsigned int i, j;
2338  // ellipse (x-cx)^2 / rx^2 + (y-cy)^2 / ry^2 = 1
2339  // -> x=+- sqrt(1-((x-cx)/rx)^2)*ry+cx
2340  // -> y=+- sqrt(1-((y-cy)/ry)^2)*rx+cy
2341  // for horizontal and vertical lines through the focal point fx,fy
2342  // we can already precalculate the value under the square root
2343  // which determines the number of solutions
2344  // for vertical lines (x=fx) it is
2345  const double s = 1 - pow((fx - cx) / rx, 2);
2346  // for horizontal lines (y=fy) it is
2347  const double t = 1 - pow((fy - cy) / ry, 2);
2348  double u = 0.0, solution1x = 0.0, solution1y = 0.0, solution2x = 0.0, solution2y = 0.0;
2349  unsigned int index = 0;
2350 
2351  for (i = 0; i < size; ++i)
2352  {
2353  for (j = 0; j < size; ++j)
2354  {
2355  delta_x = j - fx;
2356  delta_y = i - fy;
2357  double rel_distance = 1.0;
2358 
2359  if (fabs(delta_x) < ALMOST_ZERO && fabs(delta_y) < ALMOST_ZERO)
2360  {
2361  // we are on the focal point, so the rel_distance is 0.0
2362  rel_distance = 0.0;
2363  }
2364  else if (fabs(delta_x) < ALMOST_ZERO)
2365  {
2366  // use s
2367  if (s > 0.0)
2368  {
2369  // there are two crossing points
2370  solution1x = fx;
2371  // -> y=+- sqrt(s)*ry+cy
2372  solution1y = sqrt(s) * ry + cy;
2373  solution2x = fx;
2374  solution2y = -sqrt(s) * ry + cy;
2375  // we have to find out which one is the correct one
2376  // the correct one is not necessarily the one that is
2377  // closer, but the one that lies on the same side of the
2378  // focal point f(fx,fy) as the point we are looking at P(j,i)
2379  // so if the dot product is positive, we have the correct
2380  // value
2381  double dotProduct = ((double)j - fx) * (solution1x - fx) + ((double)i - fy) * (solution1y - fy);
2382 
2383  if (dotProduct <= 0)
2384  {
2385  assert(((double)j - fx) * (solution2x - fx) + ((double)i - fy) * (solution2y - fy) > 0);
2386  solution1x = solution2x;
2387  solution1y = solution2y;
2388  }
2389  }
2390  else if (fabs(s) < ALMOST_ZERO)
2391  {
2392  // there is only a tangent, so the focal points is directly
2393  // on the circle
2394  solution1x = fx;
2395  // -> y=+- sqrt(s)*rx+cy
2396  solution1y = cy;
2397  }
2398  else
2399  {
2400  // there is no crossing between the line and the circle,
2401  // since the focal points is always within the circle, this
2402  // should be impossible
2403  throw 0;
2404  }
2405  }
2406  else if (fabs(delta_y) < ALMOST_ZERO)
2407  {
2408  // use t
2409  if (t > 0.0)
2410  {
2411  // there are two crossing points
2412  solution1y = fy;
2413  // -> x=+- sqrt(t)*rx+cx
2414  solution1x = sqrt(t) * rx + cx;
2415  solution2y = fy;
2416  solution2x = -sqrt(t) * rx + cx;
2417  // we have to find out which one is the correct one
2418  // the correct one is not necessarily the one that is
2419  // closer, but the one that lies on the same side of the
2420  // focal point f(fx,fy) as the point we are looking at P(j,i)
2421  // so if the dot product is positive, we have the correct
2422  // value
2423  double dotProduct = ((double)j - fx) * (solution1x - fx) + ((double)i - fy) * (solution1y - fy);
2424 
2425  if (dotProduct < 0)
2426  {
2427  assert(((double)j - fx) * (solution2x - fx) + ((double)i - fy) * (solution2y - fy) > 0);
2428  solution1x = solution2x;
2429  solution1y = solution2y;
2430  }
2431  }
2432  else if (fabs(t) < ALMOST_ZERO)
2433  {
2434  // there is only a tangent, so the focal points is directly
2435  // on the circle
2436  solution1y = fy;
2437  // -> x=+- sqrt(t)*ry+cx
2438  solution1x = cx;
2439  }
2440  else
2441  {
2442  // there is no crossing between the line and the circle,
2443  // since the focal points is always within the circle, this
2444  // should be impossible
2445  throw 0;
2446  }
2447  }
2448  else
2449  {
2450  slope = delta_y / delta_x;
2451  // for the general case, we have to calculate the value under
2452  // the square root for every single point
2453  // a=fy-slope*fx;
2454  // u=B^2-4*A*C
2455  // u=(-2*cx*(ry)^2+2*rx^2*slope*(a-cy))^2-4*(ry^2+rx^2*slope^2)*(ry^2*cx^2+rx^2*(a-cy)^2-rx^2*ry^2)
2456  // u=(-2*cx*(ry)^2+2*rx^2*slope*(fy-slope*fx-cy))^2-4*(ry^2+rx^2*slope^2)*(ry^2*cx^2+rx^2*(fy-slope*fx-cy)^2-rx^2*ry^2)
2457  a = fy - slope * fx;
2458  A = ry * ry + rx * rx * slope * slope;
2459  B = -2 * cx * ry * ry + 2 * rx * rx * slope * (a - cy);
2460  C = ry * ry * cx * cx + rx * rx * pow(a - cy, 2) - rx * rx * ry * ry;
2461  u = B * B - 4 * A * C;
2462 
2463  if (u > 0.0)
2464  {
2465  // two solutions
2466  solution1x = (-B + sqrt(u)) / (2 * A);
2467  solution2x = (-B - sqrt(u)) / (2 * A);
2468  solution1y = solution1x * slope + a;
2469  solution2y = solution2x * slope + a;
2470  // we have to find out which one is the correct one
2471  // the correct one is not necessarily the one that is
2472  // closer, but the one that lies on the same side of the
2473  // focal point f(fx,fy) as the point we are looking at P(j,i)
2474  // so if the dot product is positive, we have the correct
2475  // value
2476  double dotProduct = ((double)j - fx) * (solution1x - fx) + ((double)i - fy) * (solution1y - fy);
2477 
2478  if (dotProduct < 0)
2479  {
2480  assert(((double)j - fx) * (solution2x - fx) + ((double)i - fy) * (solution2y - fy) > 0);
2481  solution1x = solution2x;
2482  solution1y = solution2y;
2483  }
2484  }
2485  else if (fabs(u) < ALMOST_ZERO)
2486  {
2487  // one solution, the focal point is on the circle
2488  solution1x = (-2 * slope * (fy - slope * fx) + cy) / (2 * (ry * ry + rx * rx * slope * slope));
2489  solution1y = solution1x * slope + (fy - slope * fx);
2490  }
2491  else
2492  {
2493  // no solution. Since the focal point is always in or on
2494  // the circle, this should be impossible
2495  throw 0;
2496  }
2497  }
2498 
2499  // now we have the correct crosing point in solution1x and
2500  // solution1y
2501  // we have to find out if the solution coincides with the focal
2502  // point
2503  // TODO, actually this could simplify the code above. If we get
2504  // only one solution, we actually know that it must be the focal
2505  // point
2506  if (fabs(solution1x - fx) >= ALMOST_ZERO || fabs(solution1y - fx) >= ALMOST_ZERO)
2507  {
2508  // we calculate the distance from the focal point to the
2509  // current point
2510  // and we calculate the distance from the focal point to the
2511  // crossing point
2512  // TODO we can save one square root calculation if we only
2513  // calculate the square root of the rel_distance
2514  double distance_f_c = sqrt(pow((solution1x - fx), 2) + pow((solution1y - fy), 2));
2515  double distance_f_p = sqrt(pow((j - fx), 2) + pow((i - fy), 2));
2516  rel_distance = distance_f_p / distance_f_c;
2517  }
2518 
2519  stops.update_color(rel_distance);
2520  pData[index] = stops.color().mR;
2521  pData[++index] = stops.color().mG;
2522  pData[++index] = stops.color().mB;
2523  pData[++index] = stops.color().mA;
2524  ++index;
2525  }
2526  }
2527 }
const CLRelAbsVector & getRadius() const
const CLRelAbsVector & getCenterY() const
const CLRelAbsVector & getCenterX() const
static const double ALMOST_ZERO
double getRelativeValue() const
const CLRelAbsVector & getFocalPointY() const
std::map< std::string, CLRGBAColor > mColorMap
double getAbsoluteValue() const
const CLRelAbsVector & getFocalPointX() const
void CLLayoutRenderer::createGLMatrix ( const double *const  matrix,
GLdouble *  glMatrix 
)
staticprotected

Definition at line 3185 of file CLLayoutRenderer.cpp.

Referenced by draw_curve(), draw_datapoints(), draw_group(), draw_image(), and draw_text().

3186 {
3187  glMatrix[0] = matrix[0];
3188  glMatrix[1] = matrix[1];
3189  glMatrix[2] = matrix[2];
3190  glMatrix[3] = 0.0;
3191  glMatrix[4] = matrix[3];
3192  glMatrix[5] = matrix[4];
3193  glMatrix[6] = matrix[5];
3194  glMatrix[7] = 0.0;
3195  glMatrix[8] = matrix[6];
3196  glMatrix[9] = matrix[7];
3197  glMatrix[10] = matrix[8];
3198  glMatrix[11] = 0.0;
3199  glMatrix[12] = matrix[9];
3200  glMatrix[13] = matrix[10];
3201  glMatrix[14] = matrix[11];
3202  glMatrix[15] = 1.0;
3203 }
CLLineStippleTexture * CLLayoutRenderer::createLineStippleTexture ( const std::vector< unsigned int > &  dasharray)
staticprotected

Creates a 1D texture for the line stippling. The caller is responsible for deleting the returned object. If the dasharray does not contain a valid stipple pattern NULL is returned.

Definition at line 3211 of file CLLayoutRenderer.cpp.

Referenced by update_textures_and_colors().

3212 {
3213  return new CLLineStippleTexture(dasharray);
3214 }
double CLLayoutRenderer::distance ( const CLPoint p1,
const CLPoint p2 
)
static

calculates the distance between two layout points.

Definition at line 7136 of file CLLayoutRenderer.cpp.

References CLPoint::getX(), and CLPoint::getY().

Referenced by distancePointLineSegment(), isSegmentHit(), CQGLLayoutPainter::mouseMoveEvent(), update_associations(), and CQGLLayoutPainter::update_status_and_cursor().

7137 {
7138  return sqrt(pow(p1.getX() - p2.getX(), 2) + pow(p1.getY() - p2.getY(), 2));
7139 }
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
double CLLayoutRenderer::distancePointLineSegment ( double  x,
double  y,
double  lx1,
double  ly1,
double  lx2,
double  ly2 
)
staticprotected

Calculates the distance between a point and a line segment. It tries to calculate the intersection point of the line and another line perpendicular to the first line through the given point. If this intersection point is on the line segment, the result is the same as the distance between the two lines, otherwise the distance is the distance of the given point to the closest endpoint of the segment.

Definition at line 5418 of file CLLayoutRenderer.cpp.

References distance().

Referenced by isSegmentHit().

5419 {
5420  double dx = lx2 - lx1;
5421  double dy = ly2 - ly1;
5422  double distance = std::numeric_limits<double>::quiet_NaN();
5423 
5424  if (fabs(dx) <= 1e-9)
5425  {
5426  if (fabs(dy) > 1e-9)
5427  {
5428  if (y >= ((ly1 < ly2) ? ly1 : ly2) && y <= ((ly1 > ly2) ? ly1 : ly2))
5429  {
5430  distance = fabs(lx1 - x);
5431  }
5432  }
5433  }
5434  else if (fabs(dy) <= 1e-9)
5435  {
5436  if (x >= ((lx1 < lx2) ? lx1 : lx2) && x <= ((lx1 > lx2) ? lx1 : lx2))
5437  {
5438  distance = fabs(ly1 - y);
5439  }
5440  }
5441  else
5442  {
5443  double slope = dy / dx;
5444  double invslope = -1.0 * dx / dy;
5445  double xCross = (-invslope * x + slope * lx1 + y - ly1) / (slope - invslope);
5446 
5447  if ((xCross >= ((lx1 < lx2) ? lx1 : lx2)) && (xCross <= (((lx1 > lx2) ? lx1 : lx2))))
5448  {
5449  double yCross = slope * (xCross - lx1) + ly1;
5450 
5451  if ((yCross >= ((ly1 < ly2) ? ly1 : ly2)) && (yCross <= (((ly1 > ly2) ? ly1 : ly2))))
5452  {
5453  distance = sqrt(pow(x - xCross, 2) + pow(y - yCross, 2));
5454  }
5455  else
5456  {
5457  if (fabs(lx1 - xCross) < fabs(lx2 - xCross))
5458  {
5459  // the distance to lx2.ly2 is smaller
5460  distance = sqrt(pow(x - lx2, 2) + pow(y - ly2, 2));
5461  }
5462  else
5463  {
5464  distance = sqrt(pow(x - lx1, 2) + pow(y - ly1, 2));
5465  }
5466  }
5467  }
5468  else
5469  {
5470  if (fabs(lx1 - xCross) < fabs(lx2 - xCross))
5471  {
5472  // the distance to lx2.ly2 is smaller
5473  distance = sqrt(pow(x - lx2, 2) + pow(y - ly2, 2));
5474  }
5475  else
5476  {
5477  distance = sqrt(pow(x - lx1, 2) + pow(y - ly1, 2));
5478  }
5479  }
5480  }
5481 
5482  return distance;
5483 }
static double distance(const CLPoint &p1, const CLPoint &p2)
void CLLayoutRenderer::draw_cap ( double  x1,
double  y1,
double  z1,
double  x2,
double  y2,
double  z2,
double  x3,
double  y3,
double  z3,
double  stroke_width 
)
protected

Routine to draw the caps between two line segments. The method takes the three points that make the two line segments and the width of the line.

Definition at line 4164 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO, calculate_intersection(), CLPoint::getX(), CLPoint::getY(), and CLPoint::getZ().

Referenced by draw_datapoints(), and draw_line().

4165 {
4166  // calculate the direction vector
4167  double vx1 = x2 - x1;
4168  double vy1 = y2 - y1;
4169  double vz1 = z2 - z1;
4170  double length = sqrt(vx1 * vx1 + vy1 * vy1 + vz1 * vz1);
4171 
4172  double normLength1, normLength2;
4173 
4174  // calculate the normal to this vector
4175  double vx2 = 0.0;
4176  double vy2 = 0.0;
4177  double vz2 = 0.0;
4178  double half_width = stroke_width / 2.0;
4179 
4180  if (fabs(vx1) < ALMOST_ZERO && vz1 < ALMOST_ZERO)
4181  {
4182  // scale by the stroke_width
4183  vx2 = -vy1 / length * half_width;
4184  vy2 = 0.0;
4185  vz2 = 0.0;
4186  }
4187  else
4188  {
4189  // scale by the stroke_width
4190  double normY = vy1 / length;
4191  vx2 = -normY * vx1 / length * half_width;
4192  vy2 = (1 - normY * normY) * half_width;
4193  vz2 = -normY * vz1 / length * half_width;
4194  normLength1 = half_width / sqrt(vx2 * vx2 + vy2 * vy2 + vz2 * vz2);
4195  vx2 *= normLength1;
4196  vy2 *= normLength1;
4197  vz2 *= normLength1;
4198  }
4199 
4200  // calculate the direction vector
4201  double vx3 = x3 - x2;
4202  double vy3 = y3 - y2;
4203  double vz3 = z3 - z2;
4204  double length2 = sqrt(vx3 * vx3 + vy3 * vy3 + vz3 * vz3);
4205 
4206  // calculate the normal to this vector
4207  double vx4 = 0.0;
4208  double vy4 = 0.0;
4209  double vz4 = 0.0;
4210 
4211  if (fabs(vx3) < ALMOST_ZERO && vz3 < ALMOST_ZERO)
4212  {
4213  // scale by the stroke_width
4214  vx4 = -vy3 / length2 * half_width;
4215  vy4 = 0.0;
4216  vz4 = 0.0;
4217  }
4218  else
4219  {
4220  // scale by the stroke_width
4221  double normY = vy3 / length2;
4222  vx4 = -normY * vx3 / length2 * half_width;
4223  vy4 = (1 - normY * normY) * half_width;
4224  vz4 = -normY * vz3 / length2 * half_width;
4225  normLength2 = half_width / sqrt(vx4 * vx4 + vy4 * vy4 + vz4 * vz4);
4226  vx4 *= normLength2;
4227  vy4 *= normLength2;
4228  vz4 *= normLength2;
4229  }
4230 
4231  double length3 = sqrt(pow(x3 - x1, 2) + pow(y3 - y1, 2) + pow(z3 - z1, 2));
4232  double angle = (vx2 * vx4 + vy2 * vy4 + vz2 * vz4) / (sqrt(vx2 * vx2 + vy2 * vy2 + vz2 * vz2) * sqrt(vx4 * vx4 + vy4 * vy4 + vz4 * vz4));
4233  angle = acos(angle);
4234 
4235  // if the angle is not +/-0 or +/-180°
4236  if ((fabs(angle) > ALMOST_ZERO) && (fabs((fabs(angle) - M_PI)) / M_PI > ALMOST_ZERO))
4237  {
4238  // if the angle is greater 0, the gap is at the lower edge
4239  // else the gap is at the upper edge
4240  // calculate the center of the first line segment box
4241  // in order to draw the cap, we have to find the box point at the start
4242  // edge of the second segment that is not inside the box determined by the first segment.
4243  // This is the point that is further away from the center of the first box.
4244  double xx = (x2 + x1) / 2.0;
4245  double yy = (y2 + y1) / 2.0;
4246  double zz = (z2 + z1) / 2.0;
4247  double x21 = x2 + vx4;
4248  double y21 = y2 + vy4;
4249  double z21 = z2 + vz4;
4250  double x22 = x2 - vx4;
4251  double y22 = y2 - vy4;
4252  double z22 = z2 - vz4;
4253  double distance1 = sqrt(pow(x21 - xx, 2) + pow(y21 - yy, 2) + pow(z21 - zz, 2));
4254 
4255  if (distance1 > sqrt(pow(x22 - xx, 2) + pow(y22 - yy, 2) + pow(z22 - zz, 2)))
4256  {
4257  xx = (x3 + x2) / 2.0;
4258  yy = (y3 + y2) / 2.0;
4259  zz = (y3 + y2) / 2.0;
4260  double x23 = x2 + vx2;
4261  double y23 = y2 + vy2;
4262  double z23 = z2 + vz2;
4263  x22 = x2 - vx2;
4264  y22 = y2 - vy2;
4265  z22 = z2 - vz2;
4266  double distance1 = sqrt(pow(x23 - xx, 2) + pow(y23 - yy, 2) + pow(z23 - zz, 2));
4267 
4268  if (distance1 > sqrt(pow(x22 - xx, 2) + pow(y22 - yy, 2) + pow(z22 - zz, 2)))
4269  {
4270  if (angle < M_PI / 2.0 && (length3 > length && length3 > length2))
4271  {
4272  glBegin(GL_TRIANGLES);
4273  glVertex3d(x2, y2, z2);
4274  glVertex3d(x21, y21, z21);
4275  glVertex3d(x23, y23, z23);
4276  glEnd();
4277  }
4278  else
4279  {
4280  // we need to draw two triangles
4281  const CLPoint* pP = CLLayoutRenderer::calculate_intersection(x21, y21, z21, vx3, vy3, vz3, x23, y23, z23, vx1, vy1, vz1);
4282  glBegin(GL_TRIANGLE_FAN);
4283  glVertex3d(pP->getX(), pP->getY(), pP->getZ());
4284  glVertex3d(x21, y21, z21);
4285  glVertex3d(x2, y2, z2);
4286  glVertex3d(x23, y23, z23);
4287  glEnd();
4288  delete pP;
4289  }
4290  }
4291  else
4292  {
4293  if (angle < M_PI / 2.0 && (length3 > length && length3 > length2))
4294  {
4295  glBegin(GL_TRIANGLES);
4296  glVertex3d(x2, y2, z2);
4297  glVertex3d(x21, y21, z21);
4298  glVertex3d(x22, y22, z22);
4299  glEnd();
4300  }
4301  else
4302  {
4303  // we need to draw two triangles
4304  const CLPoint* pP = CLLayoutRenderer::calculate_intersection(x21, y21, z21, vx3, vy3, vz3, x22, y22, z22, vx1, vy1, vz1);
4305  glBegin(GL_TRIANGLE_FAN);
4306  glVertex3d(pP->getX(), pP->getY(), pP->getZ());
4307  glVertex3d(x21, y21, z21);
4308  glVertex3d(x2, y2, z2);
4309  glVertex3d(x22, y22, z22);
4310  glEnd();
4311  delete pP;
4312  }
4313  }
4314  }
4315  else
4316  {
4317  xx = (x3 + x2) / 2.0;
4318  yy = (y3 + y2) / 2.0;
4319  zz = (y3 + y2) / 2.0;
4320  double x23 = x2 + vx2;
4321  double y23 = y2 + vy2;
4322  double z23 = z2 + vz2;
4323  x21 = x2 - vx2;
4324  y21 = y2 - vy2;
4325  z21 = z2 - vz2;
4326  double distance1 = sqrt(pow(x23 - xx, 2) + pow(y23 - yy, 2) + pow(z23 - zz, 2));
4327 
4328  if (distance1 > sqrt(pow(x21 - xx, 2) + pow(y21 - yy, 2) + pow(z21 - zz, 2)))
4329  {
4330  if (angle < M_PI / 2.0 && length3 > length && length3 > length2)
4331  {
4332  glBegin(GL_TRIANGLES);
4333  glVertex3d(x2, y2, z2);
4334  glVertex3d(x22, y22, z22);
4335  glVertex3d(x23, y23, z23);
4336  glEnd();
4337  }
4338  else
4339  {
4340  // we need to draw two triangles
4341  const CLPoint* pP = CLLayoutRenderer::calculate_intersection(x22, y22, z22, vx3, vy3, vz3, x23, y23, z23, vx1, vy1, vz1);
4342  glBegin(GL_TRIANGLE_FAN);
4343  glVertex3d(pP->getX(), pP->getY(), pP->getZ());
4344  glVertex3d(x22, y22, z22);
4345  glVertex3d(x2, y2, z2);
4346  glVertex3d(x23, y23, z23);
4347  glEnd();
4348  delete pP;
4349  }
4350  }
4351  else
4352  {
4353  if (angle < M_PI / 2.0 && length3 > length && length3 > length2)
4354  {
4355  glBegin(GL_TRIANGLES);
4356  glVertex3d(x2, y2, z2);
4357  glVertex3d(x22, y22, z22);
4358  glVertex3d(x21, y21, z21);
4359  glEnd();
4360  }
4361  else
4362  {
4363  // we need to draw two triangles
4364  const CLPoint* pP = CLLayoutRenderer::calculate_intersection(x22, y22, z22, vx3, vy3, vz3, x21, y21, z21, vx1, vy1, vz1);
4365  glBegin(GL_TRIANGLE_FAN);
4366  glVertex3d(pP->getX(), pP->getY(), pP->getZ());
4367  glVertex3d(x22, y22, z22);
4368  glVertex3d(x2, y2, z2);
4369  glVertex3d(x21, y21, z21);
4370  glEnd();
4371  delete pP;
4372  }
4373  }
4374  }
4375  }
4376 }
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
static const double ALMOST_ZERO
static CLPoint * calculate_intersection(double p1x, double p1y, double p1z, double sx, double sy, double sz, double p2x, double p2y, double p2z, double tx, double ty, double tz)
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
void CLLayoutRenderer::draw_curve ( const CLCurve pCurve,
bool  drawBasepoints = false 
)
protected

Method that draws a curve from the layout extension. All the other parameter like color, linewidth etc. have to be set before.

Definition at line 353 of file CLLayoutRenderer.cpp.

References calculate_cubicbezier(), createGLMatrix(), draw_line(), CLLineSegment::getBase1(), CLLineSegment::getBase2(), CLLineSegment::getEnd(), CLTransformation::getIdentityMatrix(), CLCurve::getNumCurveSegments(), CLCurve::getSegmentAt(), CLLineSegment::getStart(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), CLLineSegment::isBezier(), CLRGBAColor::mA, map_arrow_head(), CLRGBAColor::mB, mColorMap, mCurrentAttributes, CLGroupAttributes::mEndHead, CLRGBAColor::mG, CLGroupAttributes::mpTransform, CLRGBAColor::mR, CLGroupAttributes::mStartHead, CLGroupAttributes::mStroke, CLGroupAttributes::mStrokeWidth, simple_point::mX, CLGroupAttributes::mX, simple_point::mY, simple_point::mZ, NUM_BEZIER_POINTS, and NUM_CIRCLE_SEGMENTS.

Referenced by draw_group(), and draw_layout().

354 {
355  // set some attributes from mCurrentAttributes (stroke, stroke_width,
356  // stroke_dasharray)
357  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
358  assert(pos != this->mColorMap.end());
359  const CLRGBAColor& c = pos->second;
360  glColor4ub(c.mR, c.mG, c.mB, c.mA);
361  size_t i, iMax = pCurve->getNumCurveSegments();
362  const CLLineSegment* pLineSegment = NULL;
363  // apply the current transformation
364  glMatrixMode(GL_MODELVIEW);
365  glPushMatrix();
366 
367  if (memcmp(mCurrentAttributes.mpTransform, CLTransformation::getIdentityMatrix(), 12 * sizeof(double)))
368  {
369  // move back to the current offset
370  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
371  GLdouble* matrix = new GLdouble[16];
373  glMultMatrixd(matrix);
374  delete[] matrix;
375  // move to 0.0,0.0,0.0
376  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
377  }
378 
379  // calculate the data points
380  std::vector<simple_point> v;
381  simple_point p;
382  const CLPoint* pP;
383  const CLPoint* pP2, *pP3, *pP4;
384  GLdouble* pData = NULL;
385  CLPoint lastEnd;
386  double delta_phi = 2 * M_PI / NUM_CIRCLE_SEGMENTS;
387  double phi = 0.0;
388  GLdouble* pCircleData = NULL;
389 
390  // if we need to draw the basepoints of a curve,
391  // we calculate the circle points here.
392  // TODO We could actually move this code somewhere else and
393  // TODO calculate it only once at startup, but for now this works well enough
394  if (drawBasepoints == true)
395  {
396  pCircleData = new GLdouble[3 * (NUM_CIRCLE_SEGMENTS + 2)];
397  pCircleData[0] = 0.0;
398  pCircleData[1] = 0.0;
399  pCircleData[2] = 0.0;
400 
401  for (i = 1; i <= NUM_CIRCLE_SEGMENTS; ++i)
402  {
403  phi = i * delta_phi;
404  pCircleData[i * 3] = cos(phi);
405  pCircleData[i * 3 + 1] = sin(phi);
406  pCircleData[i * 3 + 2] = 0.0;
407  }
408 
409  // close the circle
410  pCircleData[i * 3] = pCircleData[3];
411  pCircleData[i * 3 + 1] = pCircleData[4];
412  pCircleData[i * 3 + 2] = pCircleData[5];
413  }
414 
415  for (i = 0; i < iMax; ++i)
416  {
417  pLineSegment = pCurve->getSegmentAt(i);
418 
419  if (pLineSegment->isBezier())
420  {
421  pP = &pLineSegment->getStart();
422 
423  // check if we have a break in the line
424  if (i != 0 && !((*pP) == lastEnd))
425  {
426  // draw the lines the are currently in v and clear v
427  iMax = v.size();
428 
429  if (iMax > 1)
430  {
431  pData = new GLdouble[3 * iMax];
432  size_t index = 0;
433  const simple_point* pSimple = NULL;
434 
435  for (i = 0; i < iMax; ++i)
436  {
437  pSimple = &v[i];
438  pData[index++] = pSimple->mX;
439  pData[index++] = pSimple->mY;
440  pData[index++] = pSimple->mZ;
441  }
442 
443  // draw the line
444  this->draw_line(iMax, pData);
445  delete[] pData;
446  }
447 
448  v.clear();
449  }
450 
451  pP2 = &pLineSegment->getEnd();
452  lastEnd = *pP2;
453  pP3 = &pLineSegment->getBase1();
454  pP4 = &pLineSegment->getBase2();
455  pData = new GLdouble[3 * NUM_BEZIER_POINTS];
457  pP3->getX(), pP3->getY(), pP3->getZ(),
458  pP4->getX(), pP4->getY(), pP4->getZ(),
459  pP2->getX(), pP2->getY(), pP2->getZ(),
460  NUM_BEZIER_POINTS, pData);
461  size_t j;
462  size_t index = 0;
463 
464  for (j = 0; j < NUM_BEZIER_POINTS; ++j)
465  {
466  p.mX = pData[index++];
467  p.mY = pData[index++];
468  p.mZ = pData[index++];
469  v.push_back(p);
470  }
471 
472  delete[] pData;
473 
474  // draw the base points if requested
475  if (drawBasepoints == true)
476  {
477  // we have to draw four circles in the same color as the line,
478  // but a little wider
480  {
481  size_t j;
482  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
483  const CLRGBAColor& c = pos->second;
484  glColor4ub(c.mR, c.mG, c.mB, c.mA);
485  glPushMatrix();
486  glTranslated(pP->getX(), pP->getY(), pP->getZ());
488  glBegin(GL_TRIANGLE_FAN);
489  glVertex3f(0.0, 0.0, 0.0);
490 
491  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
492  {
493  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
494  }
495 
496  glEnd();
497  glPopMatrix();
498  glPushMatrix();
499  glTranslated(pP2->getX(), pP2->getY(), pP2->getZ());
501  glBegin(GL_TRIANGLE_FAN);
502  glVertex3d(0.0, 0.0, 0.0);
503 
504  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
505  {
506  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
507  }
508 
509  glEnd();
510  glPopMatrix();
511  glPushMatrix();
512  glTranslated(pP3->getX(), pP3->getY(), pP3->getZ());
514  glBegin(GL_TRIANGLE_FAN);
515  glVertex3d(0.0, 0.0, 0.0);
516 
517  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
518  {
519  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
520  }
521 
522  glEnd();
523  glPopMatrix();
524  glPushMatrix();
525  glTranslated(pP4->getX(), pP4->getY(), pP4->getZ());
527  glBegin(GL_TRIANGLE_FAN);
528  glVertex3d(0.0, 0.0, 0.0);
529 
530  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
531  {
532  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
533  }
534 
535  glEnd();
536  glPopMatrix();
537  }
538  }
539  }
540  else
541  {
542  const CLPoint* pP = &pLineSegment->getStart();
543 
544  if (i != 0 && !((*pP) == lastEnd))
545  {
546  // draw the lines that are currently in v and clear v
547  iMax = v.size();
548 
549  if (iMax > 1)
550  {
551  pData = new GLdouble[3 * iMax];
552  size_t index = 0;
553  const simple_point* pSimple = NULL;
554 
555  for (i = 0; i < iMax; ++i)
556  {
557  pSimple = &v[i];
558  pData[index++] = pSimple->mX;
559  pData[index++] = pSimple->mY;
560  pData[index++] = pSimple->mZ;
561  }
562 
563  // draw the line
564  this->draw_line(iMax, pData);
565  delete[] pData;
566  }
567  }
568 
569  p.mX = pP->getX();
570  p.mY = pP->getY();
571  p.mZ = pP->getZ();
572  v.push_back(p);
573 
574  if (drawBasepoints == true)
575  {
576  // we have to draw four circles in the same color as the line,
577  // but a little wider
579  {
580  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
581  const CLRGBAColor& c = pos->second;
582  glColor4ub(c.mR, c.mG, c.mB, c.mA);
583  glPushMatrix();
584  glTranslated(pP->getX(), pP->getY(), pP->getZ());
586  glBegin(GL_TRIANGLE_FAN);
587  glVertex3d(0.0, 0.0, 0.0);
588  size_t j;
589 
590  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
591  {
592  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
593  }
594 
595  glEnd();
596  glPopMatrix();
597  }
598  }
599 
600  pP = &pLineSegment->getEnd();
601  lastEnd = *pP;
602  p.mX = pP->getX();
603  p.mY = pP->getY();
604  p.mZ = pP->getZ();
605  v.push_back(p);
606 
607  if (drawBasepoints == true)
608  {
609  // we have to draw four circles in the same color as the line,
610  // but a little wider
612  {
613  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
614  const CLRGBAColor& c = pos->second;
615  glColor4ub(c.mR, c.mG, c.mB, c.mA);
616  glPushMatrix();
617  glTranslated(pP->getX(), pP->getY(), pP->getZ());
619  glBegin(GL_TRIANGLE_FAN);
620  glVertex3d(0.0, 0.0, 0.0);
621  size_t j;
622 
623  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
624  {
625  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
626  }
627 
628  glEnd();
629  glPopMatrix();
630  }
631  }
632  }
633  }
634 
635  iMax = v.size();
636 
637  if (iMax > 1)
638  {
639  pData = new GLdouble[3 * iMax];
640  size_t index = 0;
641  const simple_point* pSimple = NULL;
642 
643  for (i = 0; i < iMax; ++i)
644  {
645  pSimple = &v[i];
646  pData[index++] = pSimple->mX;
647  pData[index++] = pSimple->mY;
648  pData[index++] = pSimple->mZ;
649  }
650 
651  // draw the line
652  this->draw_line(iMax, pData);
653  delete[] pData;
654 
655  if (drawBasepoints == true)
656  {
657  // we have to draw four circles in the same color as the line,
658  // but a little wider
660  {
661  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
662  const CLRGBAColor& c = pos->second;
663  glColor4ub(c.mR, c.mG, c.mB, c.mA);
664  glPushMatrix();
665  glTranslated(pSimple->mX, pSimple->mY, pSimple->mZ);
667  glBegin(GL_TRIANGLE_FAN);
668  glVertex3d(0.0, 0.0, 0.0);
669  size_t j;
670 
671  for (j = 0; j <= NUM_CIRCLE_SEGMENTS + 1; ++j)
672  {
673  glVertex3d(pCircleData[3 * j], pCircleData[3 * j + 1], pCircleData[3 * j + 2]);
674  }
675 
676  glEnd();
677  glPopMatrix();
678  }
679  }
680  }
681 
682  if (pCircleData != NULL) delete[] pCircleData;
683 
685  {
686  const CLLineSegment* pLS = pCurve->getSegmentAt(0);
687  const CLPoint* pP = &pLS->getStart();
688  CLPoint v;
689 
690  if (!pLS->isBezier())
691  {
692  v = CLPoint(pLS->getStart().getX() - pLS->getEnd().getX(), pLS->getStart().getY() - pLS->getEnd().getY(), pLS->getStart().getZ() - pLS->getEnd().getZ());
693  }
694  else
695  {
696  v = CLPoint(pLS->getStart().getX() - pLS->getBase1().getX(), pLS->getStart().getY() - pLS->getBase1().getY(), pLS->getStart().getZ() - pLS->getBase1().getZ());
697  }
698 
700  }
701 
702  if (!mCurrentAttributes.mEndHead.empty() && mCurrentAttributes.mEndHead != "none")
703  {
704  const CLLineSegment* pLS = pCurve->getSegmentAt(pCurve->getNumCurveSegments() - 1);
705  const CLPoint* pP = &pLS->getEnd();
706  CLPoint v;
707 
708  if (!pLS->isBezier())
709  {
710  v = CLPoint(pLS->getEnd().getX() - pLS->getStart().getX(), pLS->getEnd().getY() - pLS->getStart().getY(), pLS->getEnd().getZ() - pLS->getStart().getZ());
711  }
712  else
713  {
714  v = CLPoint(pLS->getEnd().getX() - pLS->getBase2().getX(), pLS->getEnd().getY() - pLS->getBase2().getY(), pLS->getEnd().getZ() - pLS->getBase2().getZ());
715  }
716 
718  }
719 
720  glMatrixMode(GL_MODELVIEW);
721  glPopMatrix();
722 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
static void calculate_cubicbezier(double sx, double sy, double sz, double p1x, double p1y, double p1z, double p2x, double p2y, double p2z, double ex, double ey, double ez, unsigned int numPoints, GLdouble *pData)
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
static const unsigned int NUM_CIRCLE_SEGMENTS
unsigned char mG
Definition: CLRGBAColor.h:14
unsigned char mB
Definition: CLRGBAColor.h:16
std::string mEndHead
unsigned char mA
Definition: CLRGBAColor.h:18
void map_arrow_head(const CLPoint &p, const CLPoint &v, const std::string &headId)
unsigned char mR
Definition: CLRGBAColor.h:12
static const double * getIdentityMatrix()
const CLPoint & getBase1() const
Definition: CLCurve.h:82
CLGroupAttributes mCurrentAttributes
const CLPoint & getBase2() const
Definition: CLCurve.h:83
const CLPoint & getEnd() const
Definition: CLCurve.h:75
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
std::map< std::string, CLRGBAColor > mColorMap
static const unsigned int NUM_BEZIER_POINTS
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
bool isBezier() const
Definition: CLCurve.h:90
const CLLineSegment * getSegmentAt(size_t i) const
Definition: CLCurve.h:156
std::string mStartHead
size_t getNumCurveSegments() const
Definition: CLCurve.h:168
void draw_line(size_t numPoints, GLdouble *pData)
const CLPoint & getStart() const
Definition: CLCurve.h:74
std::string mStroke
void CLLayoutRenderer::draw_curve ( const CLRenderCurve pCurve,
const CLBoundingBox pBB 
)
protected

Method that draws a curve from the render extension. All the other parameter like color, linewidth etc. have to be set before.

Definition at line 729 of file CLLayoutRenderer.cpp.

References CLRenderCubicBezier::basePoint1_X(), CLRenderCubicBezier::basePoint1_Y(), CLRenderCubicBezier::basePoint1_Z(), CLRenderCubicBezier::basePoint2_X(), CLRenderCubicBezier::basePoint2_Y(), CLRenderCubicBezier::basePoint2_Z(), calculate_cubicbezier(), convert_to_absolute(), createGLMatrix(), draw_line(), extract_1d_attributes(), extract_arrowhead_information(), CLRenderCurve::getCurveElement(), CLTransformation::getIdentityMatrix(), CLRenderCurve::getNumElements(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), map_arrow_head(), mColorMap, mCurrentAttributes, CLGroupAttributes::mEndHead, CLGroupAttributes::mpTransform, CLGroupAttributes::mStartHead, CLGroupAttributes::mStroke, simple_point::mX, CLGroupAttributes::mX, simple_point::mY, simple_point::mZ, NUM_BEZIER_POINTS, restore_current_attributes(), save_current_attributes(), CLRenderPoint::x(), CLRenderPoint::y(), and CLRenderPoint::z().

730 {
731  if (!pBB || !pCurve || pCurve->getNumElements() <= 0) return;
732 
733  this->save_current_attributes();
736  // apply the current transformation
737  glMatrixMode(GL_MODELVIEW);
738  glPushMatrix();
739 
740  if (memcmp(mCurrentAttributes.mpTransform, CLTransformation::getIdentityMatrix(), 12 * sizeof(double)))
741  {
742  // move back to the current offset
743  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
744  GLdouble* matrix = new GLdouble[16];
746  glMultMatrixd(matrix);
747  delete[] matrix;
748  // move to 0.0,0.0,0.0
749  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
750  }
751 
752  // set some attributes from mCurrentAttributes (stroke, stroke_width,
753  // stroke_dasharray)
754  if (this->mCurrentAttributes.mStroke != "none")
755  {
756  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
757  assert(pos != this->mColorMap.end());
758  const CLRGBAColor& c = pos->second;
759  glColor4ub(c.mR, c.mG, c.mB, c.mA);
760  size_t i, iMax = pCurve->getNumElements();
761  CLRenderPoint start, end, bp1, bp2;
762  CLPoint p1, p2, p3, p4;
763  const CLRenderPoint* pP = NULL;
764  const CLRenderCubicBezier* pCB = NULL;
765  // the first one has to be a point
766  const CLRenderPoint* pStart = pCurve->getCurveElement(0);
767  p1 = convert_to_absolute(pStart, pBB);
768  std::vector<simple_point> v;
769  // there are going to be at least iMax elements in the vector
770  v.reserve(iMax);
771  simple_point p;
772  p.mX = p1.getX();
773  p.mY = p1.getY();
774  p.mZ = p1.getZ();
775  v.push_back(p);
776  GLdouble* pData = NULL;
777 
778  for (i = 1; i < iMax; ++i)
779  {
780  pP = pCurve->getCurveElement(i);
781  pCB = dynamic_cast<const CLRenderCubicBezier*>(pP);
782 
783  if (pCB != NULL)
784  {
785  end = CLRenderPoint(pCB->x(), pCB->y(), pCB->z());
786  bp1 = CLRenderPoint(pCB->basePoint1_X(), pCB->basePoint1_Y(), pCB->basePoint1_Z());
787  bp2 = CLRenderPoint(pCB->basePoint2_X(), pCB->basePoint2_Y(), pCB->basePoint2_Z());
788  p2 = convert_to_absolute(&end, pBB);
789  p3 = convert_to_absolute(&bp1, pBB);
790  p4 = convert_to_absolute(&bp2, pBB);
791  pData = new GLdouble[3 * NUM_BEZIER_POINTS];
793  p3.getX(), p3.getY(), p3.getZ(),
794  p4.getX(), p4.getY(), p4.getZ(),
795  p2.getX(), p2.getY(), p2.getZ(),
796  NUM_BEZIER_POINTS, pData);
797  size_t j;
798  size_t index = 0;
799 
800  for (j = 0; j < NUM_BEZIER_POINTS; ++j)
801  {
802  p.mX = pData[index++];
803  p.mY = pData[index++];
804  p.mZ = pData[index++];
805  v.push_back(p);
806  }
807 
808  delete[] pData;
809  }
810  else
811  {
812  end = CLRenderPoint(pP->x(), pP->y(), pP->z());
813  p2 = convert_to_absolute(&end, pBB);
814  p.mX = p2.getX();
815  p.mY = p2.getY();
816  p.mZ = p2.getZ();
817  v.push_back(p);
818  }
819 
820  // this end is the next start
821  p1 = p2;
822  }
823 
824  iMax = v.size();
825 
826  if (iMax > 1)
827  {
828  pData = new GLdouble[3 * iMax];
829  size_t index = 0;
830  const simple_point* pSimple = NULL;
831 
832  for (i = 0; i < iMax; ++i)
833  {
834  pSimple = &v[i];
835  pData[index++] = pSimple->mX;
836  pData[index++] = pSimple->mY;
837  pData[index++] = pSimple->mZ;
838  }
839 
840  // draw the line
841  this->draw_line(iMax, pData);
842  delete[] pData;
843  }
844 
845  // map arrow heads
847  {
848  assert(pCurve->getNumElements() > 1);
849  const CLRenderPoint* pStart = pCurve->getCurveElement(0);
850  const CLPoint start = convert_to_absolute(pStart, pBB);
851  CLPoint v;
852  const CLRenderPoint* pEnd = pCurve->getCurveElement(1);
853  const CLRenderCubicBezier* pCB = dynamic_cast<const CLRenderCubicBezier*>(pEnd);
854 
855  if (!pCB)
856  {
857  const CLPoint end = convert_to_absolute(pEnd, pBB);
858  v = CLPoint(start.getX() - end.getX(), start.getY() - end.getY(), start.getZ() - end.getZ());
859  }
860  else
861  {
862  const CLRenderPoint* pEnd = new CLRenderPoint(pCB->basePoint1_X(), pCB->basePoint1_Y(), pCB->basePoint1_Z());
863  const CLPoint end = convert_to_absolute(pEnd, pBB);
864  delete pEnd;
865  v = CLPoint(start.getX() - end.getX(), start.getY() - end.getY(), start.getZ() - end.getZ());
866  }
867 
868  // we have to clear the arrow head attributes before we call the mapping
869  // function.
870  // If we don't do that and the line ending contains a curve, it will try
871  // to map itself to the curve again which is an endless loop.
872  this->save_current_attributes();
873  std::string headId = mCurrentAttributes.mStartHead;
874  this->map_arrow_head(start, v, headId);
875  // set the old attributes again
877  }
878 
879  if (!mCurrentAttributes.mEndHead.empty() && mCurrentAttributes.mEndHead != "none")
880  {
881  const CLRenderPoint* pEnd = pCurve->getCurveElement(pCurve->getNumElements() - 1);
882  const CLPoint end = convert_to_absolute(pEnd, pBB);
883 
884  const CLRenderCubicBezier* pCB = dynamic_cast<const CLRenderCubicBezier*>(pEnd);
885  CLPoint v;
886 
887  if (!pCB)
888  {
889  const CLRenderPoint* pStart = pCurve->getCurveElement(pCurve->getNumElements() - 2);
890  const CLPoint start = convert_to_absolute(pStart, pBB);
891  v = CLPoint(end.getX() - start.getX(), end.getY() - start.getY(), end.getZ() - start.getZ());
892  }
893  else
894  {
895  const CLRenderPoint* pStart = new CLRenderPoint(pCB->basePoint2_X(), pCB->basePoint2_Y(), pCB->basePoint2_Z());
896  const CLPoint start = convert_to_absolute(pStart, pBB);
897  delete pStart;
898  v = CLPoint(end.getX() - start.getX(), end.getY() - start.getY(), end.getZ() - start.getZ());
899  }
900 
901  // we have to clear the arrow head attributes before we call the mapping
902  // function.
903  // If we don't do that and the line ending contains a curve, it will try
904  // to map itself to the curve again which is an endless loop.
905  this->save_current_attributes();
906  std::string headId = mCurrentAttributes.mEndHead;
907  this->map_arrow_head(end, v, headId);
908  // set the old attributes again
910  }
911  }
912 
914  glMatrixMode(GL_MODELVIEW);
915  glPopMatrix();
916 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
static void calculate_cubicbezier(double sx, double sy, double sz, double p1x, double p1y, double p1z, double p2x, double p2y, double p2z, double ex, double ey, double ez, unsigned int numPoints, GLdouble *pData)
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
const CLRelAbsVector & basePoint1_X() const
const CLRelAbsVector & basePoint2_Y() const
const CLRelAbsVector & z() const
std::string mEndHead
size_t getNumElements() const
void map_arrow_head(const CLPoint &p, const CLPoint &v, const std::string &headId)
const CLRelAbsVector & basePoint2_Z() const
static const CLPoint convert_to_absolute(const CLRenderPoint *pRenderPoint, const CLBoundingBox *pBB)
const CLRelAbsVector & basePoint2_X() const
static void extract_arrowhead_information(const T *pObject, CLGroupAttributes *attributes)
static const double * getIdentityMatrix()
CLGroupAttributes mCurrentAttributes
const CLRenderPoint * getCurveElement(size_t index) const
const CLRelAbsVector & y() const
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
std::map< std::string, CLRGBAColor > mColorMap
static const unsigned int NUM_BEZIER_POINTS
static void extract_1d_attributes(const CLGraphicalPrimitive1D *pObject, CLGroupAttributes *attributes)
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
const CLRelAbsVector & basePoint1_Z() const
const CLRelAbsVector & x() const
const CLRelAbsVector & basePoint1_Y() const
std::string mStartHead
void draw_line(size_t numPoints, GLdouble *pData)
std::string mStroke
void CLLayoutRenderer::draw_datapoints ( GLdouble *  pData,
size_t  numPoints,
const CLBoundingBox pBB,
bool  doTesselation = false,
float  xOffset = 0.0,
float  yOffset = 0.0,
float  zOffset = 0.0 
)
protected

Draw a set of datapoints with the current attributes using the given bounding box.

Method to draw a render polygon from a set of datapoints

Definition at line 2693 of file CLLayoutRenderer.cpp.

References COMBINE_CALLBACK(), COMBINE_CALLBACK_GRADIENT(), createGLMatrix(), draw_cap(), draw_line(), CLGraphicalPrimitive2D::EVENODD, CCopasiMessage::EXCEPTION, CLBoundingBox::getDimensions(), CLDimensions::getHeight(), CLBoundingBox::getPosition(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), CLGraphicalPrimitive2D::INHERIT, CLRGBAColor::mA, CLRGBAColor::mB, mColorMap, mCurrentAttributes, CLGroupAttributes::mFill, CLGroupAttributes::mFillRule, CLRGBAColor::mG, mGradientMap, CLGroupAttributes::mpTransform, CLRGBAColor::mR, CLGroupAttributes::mStroke, CLGroupAttributes::mStrokeWidth, CLGroupAttributes::mX, CLGraphicalPrimitive2D::NONZERO, TESS_ERROR(), CLGraphicalPrimitive2D::UNSET, and VERTEX_CALLBACK_GRADIENT().

Referenced by draw_ellipse(), draw_polygon(), and draw_rectangle().

2694 {
2695  glMatrixMode(GL_MODELVIEW);
2696  glPushMatrix();
2697  glTranslatef(xOffset, yOffset, zOffset);
2698 
2699  // apply the current transformation
2700  if (memcmp(mCurrentAttributes.mpTransform, Transformation::getIdentityMatrix(), 12 * sizeof(double)))
2701  {
2702  // move back to the current offset
2703  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
2704  GLdouble* matrix = new GLdouble[16];
2706  glMultMatrixd(matrix);
2707  delete[] matrix;
2708  // move to 0.0,0.0,0.0
2709  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
2710  }
2711 
2712  // draw the rectangle
2713  // first we draw the filled part
2714  if (this->mCurrentAttributes.mFillRule != CLGraphicalPrimitive2D::UNSET && this->mCurrentAttributes.mFill != "none")
2715  {
2716 
2717  // tesselate the polygon to make sure that it is drawn correctly by
2718  // OpenGL
2719  GLUtesselator* pTess = NULL;
2720 
2721  if (doTesselation)
2722  {
2723  pTess = gluNewTess();
2724  }
2725 
2726  bool singleColor = true;
2727  // set the stepsize for the datapoints to 3
2728  // which means that the data array only contains vertex information
2729  // if we have a gradient, we have to set it to 5 later on
2730  // because the data now contains texture coordinates as well
2731  unsigned int stepsize = 3;
2732  GLdouble* pOrigData = pData;
2733  GLdouble* pNewData = NULL;
2734  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mFill);
2735 
2736  if (pos != this->mColorMap.end())
2737  {
2738  const CLRGBAColor& c = pos->second;
2739  glColor4ub(c.mR, c.mG, c.mB, c.mA);
2740  }
2741  else
2742  {
2743  singleColor = false;
2744  // enable tesselation if a gradient is specified
2745  pTess = gluNewTess();
2746  // it could be a gradient
2747  std::map<std::string, std::pair<const CLGradientBase*, CLTextureSpec*> >::const_iterator pos = this->mGradientMap.find(mCurrentAttributes.mFill);
2748  assert(pos != this->mGradientMap.end());
2749  const CLTextureSpec* pTexSpec = pos->second.second;
2750  assert(pTexSpec != NULL);
2751  unsigned int i;
2752 #ifdef _WIN32
2753  gluTessCallback(pTess, GLU_TESS_BEGIN, (GLvoid(__stdcall *)())glBegin);
2754  gluTessCallback(pTess, GLU_TESS_END, glEnd);
2755  gluTessCallback(pTess, GLU_TESS_VERTEX, (GLvoid(__stdcall *)())CLLayoutRenderer::VERTEX_CALLBACK_GRADIENT);
2756  gluTessCallback(pTess, GLU_TESS_COMBINE, (GLvoid(__stdcall *)())CLLayoutRenderer::COMBINE_CALLBACK_GRADIENT);
2757 #else
2758  gluTessCallback(pTess, GLU_TESS_BEGIN, (GLvoid(*)())glBegin);
2759  gluTessCallback(pTess, GLU_TESS_END, glEnd);
2760  gluTessCallback(pTess, GLU_TESS_VERTEX, (GLvoid(*)())CLLayoutRenderer::VERTEX_CALLBACK_GRADIENT);
2761  gluTessCallback(pTess, GLU_TESS_COMBINE, (GLvoid(*)())CLLayoutRenderer::COMBINE_CALLBACK_GRADIENT);
2762 #endif // _WIN32
2763  stepsize = 5;
2764  pNewData = new GLdouble[5 * numPoints];
2765  // assign the texture coordinates
2766  double width = pBB->getDimensions().getWidth();
2767  double height = pBB->getDimensions().getHeight();
2768 
2769  for (i = 0; i < numPoints; ++i)
2770  {
2771  pNewData[5 * i] = pData[3 * i];
2772  pNewData[5 * i + 1] = pData[3 * i + 1];
2773  pNewData[5 * i + 2] = pData[3 * i + 2];
2774  pNewData[5 * i + 3] = (pData[3 * i] + xOffset - pBB->getPosition().getX()) / width;
2775  pNewData[5 * i + 4] = (pData[3 * i + 1] + yOffset - pBB->getPosition().getY()) / height;
2776  }
2777 
2778  pData = pNewData;
2779 
2780  // load the texture
2781  if (pTexSpec->mTextureName != 0)
2782  {
2783  glBindTexture(GL_TEXTURE_2D, pTexSpec->mTextureName);
2784  // enable 2D texturing
2785  glEnable(GL_TEXTURE_2D);
2786  }
2787 
2788  /*
2789  else
2790  {
2791  std::cerr << "Texture not bound." << std::endl;
2792  }
2793  */
2794  }
2795 
2796  if (pTess && singleColor)
2797  {
2798  // we don't need to do anythong special during the tesselation since
2799  // the whole object only has one color
2800 #ifdef _WIN32
2801  gluTessCallback(pTess, GLU_TESS_BEGIN, (GLvoid(__stdcall *)())glBegin);
2802  gluTessCallback(pTess, GLU_TESS_END, (GLvoid(__stdcall *)())glEnd);
2803  gluTessCallback(pTess, GLU_TESS_VERTEX, (GLvoid(__stdcall *)())glVertex3dv);
2804  gluTessCallback(pTess, GLU_TESS_COMBINE, (GLvoid(__stdcall *)())CLLayoutRenderer::COMBINE_CALLBACK);
2805 #else
2806  gluTessCallback(pTess, GLU_TESS_BEGIN, (GLvoid(*)())glBegin);
2807  gluTessCallback(pTess, GLU_TESS_END, (GLvoid(*)())glEnd);
2808  gluTessCallback(pTess, GLU_TESS_VERTEX, (GLvoid(*)())glVertex3dv);
2809  gluTessCallback(pTess, GLU_TESS_COMBINE, (GLvoid(*)())CLLayoutRenderer::COMBINE_CALLBACK);
2810 #endif // _WIN32
2811  }
2812 
2813  if (pTess)
2814  {
2815  // specify the fill rule to the tesselator EVENODD, NONZERO
2816  switch (this->mCurrentAttributes.mFillRule)
2817  {
2819  // this should not happen
2820  CCopasiMessage(CCopasiMessage::EXCEPTION, "Invalid Render Information: No fill rule specified");
2821  break;
2822 
2824  gluTessProperty(pTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO);
2825  break;
2826 
2828  gluTessProperty(pTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
2829  break;
2830 
2832  // this should not happen
2833  // inherit has to be replaced by something meaningfull
2834  CCopasiMessage(CCopasiMessage::EXCEPTION, "Invalid Render Information: fill rule \"INHERIT\" specified");
2835  break;
2836  }
2837 
2838 #ifdef _WIN32
2839  gluTessCallback(pTess, GLU_TESS_ERROR, (GLvoid(__stdcall *)())CLLayoutRenderer::TESS_ERROR);
2840 #else
2841  gluTessCallback(pTess, GLU_TESS_ERROR, (GLvoid(*)())CLLayoutRenderer::TESS_ERROR);
2842 #endif // _WIN32
2843  gluTessBeginPolygon(pTess, NULL);
2844  gluTessBeginContour(pTess);
2845  // specify the actual vertex data
2846  size_t j = 0, jMax = numPoints - 1;
2847 
2848  while (j < jMax)
2849  {
2850  gluTessVertex(pTess, &pData[j * stepsize], &pData[j * stepsize]);
2851  ++j;
2852  }
2853 
2854  gluTessEndContour(pTess);
2855  gluTessEndPolygon(pTess);
2856  gluDeleteTess(pTess);
2857  pData = pOrigData;
2858 
2859  if (pNewData)
2860  {
2861  delete[] pNewData;
2862  }
2863  }
2864  else
2865  {
2866  // it must be a single colored object, so we just draw the vertex array
2867  glEnableClientState(GL_VERTEX_ARRAY);
2868  glVertexPointer(3, GL_DOUBLE, 0, pData);
2869  glDrawArrays(GL_POLYGON, 0, (GLsizei)(numPoints - 1));
2870  glDisableClientState(GL_VERTEX_ARRAY);
2871  }
2872 
2873  if (!singleColor)
2874  {
2875  // disable texturing again
2876  glDisable(GL_TEXTURE_2D);
2877  }
2878  }
2879 
2880  //
2881  // next we draw the edge
2882  //
2883  if (this->mCurrentAttributes.mStrokeWidth > 0.0 && this->mCurrentAttributes.mStroke != "none")
2884  {
2885  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
2886  assert(pos != this->mColorMap.end());
2887  const CLRGBAColor& c = pos->second;
2888  glColor4ub(c.mR, c.mG, c.mB, c.mA);
2889  this->draw_line(numPoints, pData);
2890  // draw the final cap
2891  size_t index = (numPoints - 2) * 3;
2892  draw_cap(pData[index], pData[index + 1], pData[index + 2], pData[0], pData[1], pData[2], pData[3], pData[4], pData[5], mCurrentAttributes.mStrokeWidth);
2893  }
2894 
2895  glPopMatrix();
2896 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
unsigned char mG
Definition: CLRGBAColor.h:14
unsigned char mB
Definition: CLRGBAColor.h:16
unsigned char mA
Definition: CLRGBAColor.h:18
unsigned char mR
Definition: CLRGBAColor.h:12
std::map< std::string, std::pair< const CLGradientBase *, CLTextureSpec * > > mGradientMap
CLGroupAttributes mCurrentAttributes
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
static void TESS_ERROR(GLenum error)
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const CLPoint & getPosition() const
Definition: CLBase.h:265
void draw_cap(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double stroke_width)
std::map< std::string, CLRGBAColor > mColorMap
static void COMBINE_CALLBACK(GLdouble coords[3], GLdouble **, GLfloat *, GLdouble **dataOut)
CLGraphicalPrimitive2D::FILL_RULE mFillRule
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
static void COMBINE_CALLBACK_GRADIENT(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
void draw_line(size_t numPoints, GLdouble *pData)
static void VERTEX_CALLBACK_GRADIENT(GLvoid *vertex)
std::string mStroke
void CLLayoutRenderer::draw_ellipse ( const CLEllipse pEllipse,
const CLBoundingBox pBB 
)
protected

Method to draw a render ellipse object.

Definition at line 1659 of file CLLayoutRenderer.cpp.

References draw_datapoints(), extract_2d_attributes(), CLRelAbsVector::getAbsoluteValue(), CLEllipse::getCX(), CLEllipse::getCY(), CLEllipse::getCZ(), CLDimensions::getDepth(), CLBoundingBox::getDimensions(), CLDimensions::getHeight(), CLBoundingBox::getPosition(), CLRelAbsVector::getRelativeValue(), CLEllipse::getRX(), CLEllipse::getRY(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), mCurrentAttributes, NUM_CIRCLE_SEGMENTS, restore_current_attributes(), and save_current_attributes().

Referenced by draw_group().

1660 {
1661  // store and change the attributes
1662  this->save_current_attributes();
1664  // draw the ellipse
1665  // first we calculate the data points for the ellipse
1666  double x = pBB->getPosition().getX() + pEllipse->getCX().getAbsoluteValue() + pEllipse->getCX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth();
1667  double y = pBB->getPosition().getY() + pEllipse->getCY().getAbsoluteValue() + pEllipse->getCY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight();
1668  double z = pBB->getPosition().getZ() + pEllipse->getCZ().getAbsoluteValue() + pEllipse->getCZ().getRelativeValue() / 100.0 * pBB->getDimensions().getDepth();
1669  double rx = pEllipse->getRX().getAbsoluteValue() + pEllipse->getRX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth();
1670  double ry = pEllipse->getRY().getAbsoluteValue() + pEllipse->getRY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight();
1671  // we add an additional datapoint to close the loop. This way we don't need
1672  // the draw_loop method, but all is handled in draw_line
1673  // this also makes line stippling easier for OpenGL < 2.0
1674  GLdouble* pData = new GLdouble[3 * (NUM_CIRCLE_SEGMENTS + 1)];
1675  unsigned int i;
1676  double delta_phi = 2 * M_PI / NUM_CIRCLE_SEGMENTS;
1677  double phi = 0.0;
1678  size_t index = 0;
1679 
1680  for (i = 0; i < NUM_CIRCLE_SEGMENTS; ++i)
1681  {
1682  // TODO it would be enough to calculate only one quadrant
1683  phi = i * delta_phi;
1684  pData[index++] = rx * rx * cos(phi) / sqrt(rx * rx * pow(cos(phi), 2) + ry * ry * pow(sin(phi), 2));
1685  pData[index++] = ry * ry * sin(phi) / sqrt(rx * rx * pow(cos(phi), 2) + ry * ry * pow(sin(phi), 2));
1686  pData[index++] = 0.0;
1687  }
1688 
1689  // close the loop
1690  pData[index++] = pData[0];
1691  pData[index++] = pData[1];
1692  pData[index] = pData[2];
1693  this->draw_datapoints(pData, NUM_CIRCLE_SEGMENTS + 1, pBB, false, (GLfloat)x, (GLfloat)y, (GLfloat)z);
1694  delete[] pData;
1695  // restore the attributes
1697 }
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const C_FLOAT64 & getDepth() const
Definition: CLBase.h:213
static const unsigned int NUM_CIRCLE_SEGMENTS
double getRelativeValue() const
void draw_datapoints(GLdouble *pData, size_t numPoints, const CLBoundingBox *pBB, bool doTesselation=false, float xOffset=0.0, float yOffset=0.0, float zOffset=0.0)
static void extract_2d_attributes(const CLGraphicalPrimitive2D *pObject, CLGroupAttributes *attributes)
CLGroupAttributes mCurrentAttributes
const CLRelAbsVector & getRX() const
Definition: CLEllipse.cpp:151
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const CLRelAbsVector & getCY() const
Definition: CLEllipse.cpp:135
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const CLPoint & getPosition() const
Definition: CLBase.h:265
const CLRelAbsVector & getCZ() const
Definition: CLEllipse.cpp:143
const CLRelAbsVector & getRY() const
Definition: CLEllipse.cpp:159
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
double getAbsoluteValue() const
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
const CLRelAbsVector & getCX() const
Definition: CLEllipse.cpp:127
void CLLayoutRenderer::draw_group ( const CLGroup pGroup,
const CLBoundingBox pBB 
)
protected

Method to draw an arbitrary object specified by it's bounding box and the style with which it should be drawn.

Definition at line 1346 of file CLLayoutRenderer.cpp.

References createGLMatrix(), draw_curve(), draw_ellipse(), draw_image(), draw_polygon(), draw_rectangle(), draw_text(), extract_group_attributes(), CLBoundingBox::getDimensions(), CLGroup::getElement(), CLDimensions::getHeight(), CLGroup::getNumElements(), CLBoundingBox::getPosition(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), mCurrentAttributes, CLGroupAttributes::mHeight, CLGroupAttributes::mpTransform, CLGroupAttributes::mWidth, CLGroupAttributes::mX, CLGroupAttributes::mY, CLGroupAttributes::mZ, restore_current_attributes(), and save_current_attributes().

Referenced by draw_object(), and map_arrow_head().

1347 {
1348  // set the group attributes
1349  this->save_current_attributes();
1356  glMatrixMode(GL_MODELVIEW);
1357  glPushMatrix();
1358 
1359  // apply the current transformation
1360  if (memcmp(mCurrentAttributes.mpTransform, Transformation::getIdentityMatrix(), 12 * sizeof(double)))
1361  {
1362  // move back to the current offset
1363  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
1364  GLdouble* matrix = new GLdouble[16];
1366  glMultMatrixd(matrix);
1367  delete[] matrix;
1368  // move to 0.0,0.0,0.0
1369  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
1370  }
1371 
1372  // draw each element
1373  const CCopasiObject* pObject = NULL;
1374  size_t i, iMax = pGroup->getNumElements();
1375 
1376  for (i = 0; i < iMax; ++i)
1377  {
1378  pObject = pGroup->getElement(i);
1379  assert(pObject != NULL);
1380  // find out what kind of element it is
1381  const CLEllipse* pEllipse = dynamic_cast<const CLEllipse*>(pObject);
1382 
1383  if (pEllipse != NULL)
1384  {
1385  CLLayoutRenderer::draw_ellipse(pEllipse, pBB);
1386  }
1387  else
1388  {
1389  const CLGroup* pRenderGroup = dynamic_cast<const CLGroup*>(pObject);
1390 
1391  if (pRenderGroup != NULL)
1392  {
1393  CLLayoutRenderer::draw_group(pRenderGroup, pBB);
1394  }
1395  else
1396  {
1397  const CLImage* pImage = dynamic_cast<const CLImage*>(pObject);
1398 
1399  if (pImage != NULL)
1400  {
1401  CLLayoutRenderer::draw_image(pImage, pBB);
1402  }
1403  else
1404  {
1405  const CLPolygon* pPolygon = dynamic_cast<const CLPolygon*>(pObject);
1406 
1407  if (pPolygon != NULL)
1408  {
1409  CLLayoutRenderer::draw_polygon(pPolygon, pBB);
1410  }
1411  else
1412  {
1413  const CLRectangle* pRectangle = dynamic_cast<const CLRectangle*>(pObject);
1414 
1415  if (pRectangle != NULL)
1416  {
1417  CLLayoutRenderer::draw_rectangle(pRectangle, pBB);
1418  }
1419  else
1420  {
1421  const CLRenderCurve* pCurve = dynamic_cast<const CLRenderCurve*>(pObject);
1422 
1423  if (pCurve != NULL)
1424  {
1425  CLLayoutRenderer::draw_curve(pCurve, pBB);
1426  }
1427  else
1428  {
1429  const CLText* pText = dynamic_cast<const CLText*>(pObject);
1430 
1431  if (pText != NULL)
1432  {
1433  CLLayoutRenderer::draw_text(pText, pBB);
1434  }
1435  else
1436  {
1437  throw pObject;
1438  }
1439  }
1440  }
1441  }
1442  }
1443  }
1444  }
1445  }
1446 
1447  // restore the attributes
1449  glMatrixMode(GL_MODELVIEW);
1450  glPopMatrix();
1451 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
Definition: CLText.h:27
void draw_ellipse(const CLEllipse *pEllipse, const CLBoundingBox *pBB)
static void extract_group_attributes(const CLStyle *pStyle, CLGroupAttributes *attributes)
void draw_polygon(const CLPolygon *pPolygon, const CLBoundingBox *pBB)
void draw_text(const CLStyle *pStyle, const CLBoundingBox *pBB, const CLTextTextureSpec *pTexture)
CLGroupAttributes mCurrentAttributes
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const CLPoint & getPosition() const
Definition: CLBase.h:265
CCopasiObject * getElement(size_t n)
Definition: CLGroup.cpp:409
void draw_group(const CLGroup *pGroup, const CLBoundingBox *pBB)
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
void draw_rectangle(const CLRectangle *pRectangle, const CLBoundingBox *pBB)
size_t getNumElements() const
Definition: CLGroup.cpp:384
void draw_curve(const CLCurve *pCurve, bool drawBasepoints=false)
void draw_image(const CLImage *pImage, const CLBoundingBox *pBB)
void CLLayoutRenderer::draw_image ( const CLImage pImage,
const CLBoundingBox pBB 
)
protected

Method to draw a render image object.

Definition at line 1702 of file CLLayoutRenderer.cpp.

References convert_to_absolute(), createGLMatrix(), extract_transformation_attributes(), CLRelAbsVector::getAbsoluteValue(), CLBoundingBox::getDimensions(), CLImage::getHeight(), CLDimensions::getHeight(), CLImage::getImageReference(), CLRelAbsVector::getRelativeValue(), CLImage::getWidth(), CLDimensions::getWidth(), CLImage::getX(), CLImage::getY(), CLImage::isSetImageReference(), mBaseDir, mCurrentAttributes, mImageMap, mpImageTexturizer, CLGroupAttributes::mpTransform, CLTextureSpec::mTextureName, CLGroupAttributes::mX, restore_current_attributes(), and save_current_attributes().

Referenced by draw_group().

1703 {
1704  // the ransformation attributes are the only ones that influence the
1705  // drawing of an image
1706  this->save_current_attributes();
1708  // draw the actual image
1709  const CLTextureSpec* pTexture = NULL;
1710 
1711  if (pImage->isSetImageReference())
1712  {
1713  std::string reference = pImage->getImageReference();
1714  std::map<std::string, const CLTextureSpec*>::const_iterator pos = this->mImageMap.find(reference);
1715 
1716  if (pos == this->mImageMap.end())
1717  {
1718  // we need to create the texture
1719  if (this->mpImageTexturizer != NULL)
1720  {
1721  pTexture = (*this->mpImageTexturizer)(reference, this->mBaseDir);
1722  this->mImageMap[reference] = pTexture;
1723  pos = this->mImageMap.find(reference);
1724  assert(pos != this->mImageMap.end());
1725  }
1726  }
1727 
1728  assert(pos != this->mImageMap.end());
1729  pTexture = pos->second;
1730  //assert(pTexture);
1731  }
1732 
1733  if (pTexture)
1734  {
1735  // draw the texture in the correct place
1736  // load the texture
1737  assert(pTexture->mTextureName != 0);
1738  glBindTexture(GL_TEXTURE_2D, pTexture->mTextureName);
1739  const CLDimensions* d = &pBB->getDimensions();
1740  double width = pImage->getWidth().getAbsoluteValue() + pImage->getWidth().getRelativeValue() / 100.0 * d->getWidth();
1741  double height = pImage->getHeight().getAbsoluteValue() + pImage->getHeight().getRelativeValue() / 100.0 * d->getHeight();
1742  CLRenderPoint p(pImage->getX(), pImage->getY());
1744  // apply the current transformation
1745  glMatrixMode(GL_MODELVIEW);
1746  glPushMatrix();
1747 
1748  if (memcmp(mCurrentAttributes.mpTransform, Transformation::getIdentityMatrix(), 12 * sizeof(double)))
1749  {
1750  // move back to the current offset
1751  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
1752  GLdouble* matrix = new GLdouble[16];
1754  glMultMatrixd(matrix);
1755  delete[] matrix;
1756  // move to 0.0,0.0,0.0
1757  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
1758  }
1759 
1760  // enable 2D texturing
1761  glEnable(GL_TEXTURE_2D);
1762  glMatrixMode(GL_MODELVIEW);
1763  glPushMatrix();
1764  glTranslated(point.getX(), point.getY(), point.getZ());
1765  glBegin(GL_POLYGON);
1766  glTexCoord2d(0.0, 0.0);
1767  glVertex3d(0.0, 0.0, 0.0);
1768  glTexCoord2d(0.0, 1.0);
1769  glVertex3d(0.0, height, 0.0);
1770  glTexCoord2d(1.0, 1.0);
1771  glVertex3d(width, height, 0.0);
1772  glTexCoord2d(1.0, 0.0);
1773  glVertex3d(width, 0.0, 0.0);
1774  glEnd();
1775  glPopMatrix();
1776  // disable the 2D texture again
1777  glDisable(GL_TEXTURE_2D);
1778  }
1779  else
1780  {
1781  // TODO at least create some kind of error message
1782  }
1783 
1784  // restore the attributes
1786  glMatrixMode(GL_MODELVIEW);
1787  glPopMatrix();
1788 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
CLRelAbsVector & getX()
Definition: CLImage.cpp:198
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const CLRelAbsVector & getHeight() const
Definition: CLImage.cpp:116
CLImageTexturizer * mpImageTexturizer
CLRelAbsVector & getY()
Definition: CLImage.cpp:206
double getRelativeValue() const
static const CLPoint convert_to_absolute(const CLRenderPoint *pRenderPoint, const CLBoundingBox *pBB)
CLGroupAttributes mCurrentAttributes
const std::string & getImageReference() const
Definition: CLImage.cpp:132
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
static void extract_transformation_attributes(const CLTransformation *pObject, CLGroupAttributes *attributes)
Definition: CLBase.h:54
std::map< std::string, const CLTextureSpec * > mImageMap
std::string mBaseDir
const CLRelAbsVector & getWidth() const
Definition: CLImage.cpp:108
double getAbsoluteValue() const
bool isSetImageReference() const
Definition: CLImage.cpp:222
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
void CLLayoutRenderer::draw_layout ( )

Method to draw a given layout with a given render resolver.

Definition at line 939 of file CLLayoutRenderer.cpp.

References draw_curve(), draw_object(), draw_selection_box(), draw_text(), drawSelectionBox(), extract_group_attributes(), CLColorDefinition::getAlpha(), CLRenderResolver::getBackgroundColor(), CLColorDefinition::getBlue(), CLGraphicalObject::getBoundingBox(), CLGlyphWithCurve::getCurve(), getCurveBoundingBox(), CLayout::getDimensions(), CLBoundingBox::getDimensions(), CLColorDefinition::getGreen(), CLDimensions::getHeight(), CLGraphicalObject::getModelObject(), CLCurve::getNumCurveSegments(), CCopasiObject::getObjectParent(), CLBoundingBox::getPosition(), CLColorDefinition::getRed(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), GL_FOG_COORD, GL_FOG_COORD_SRC, initialize_gl_extension_functions(), mCurrentAttributes, mDrawables, mFogColor, mFogDensity, mGLFunctionsInitialized, CLGroupAttributes::mHeight, mHighlight, mHighlightColor, mHighlightedObjects, mpGlFogCoordfEXT, mpLayout, mpResolver, mSelection, CLGroupAttributes::mStroke, CLGroupAttributes::mStrokeWidth, mStyleMap, mTextGlyphMap, CLGroupAttributes::mWidth, CLGroupAttributes::mX, CLGroupAttributes::mY, CLGroupAttributes::mZ, restore_current_attributes(), save_current_attributes(), and CLBoundingBox::setPosition().

Referenced by addToSelection(), CQGLLayoutPainter::draw(), CQGLLayoutPainter::draw_bitmap(), and removeFromSelection().

940 {
941  // first we need to clear the screen
942  // with the background color
943  glDisable(GL_POLYGON_SMOOTH);
944 
945  if (this->mGLFunctionsInitialized == false)
946  {
948  }
949 
950  glFogi(GL_FOG_MODE, GL_EXP);
951 
952  if (this->mHighlight == true)
953  {
954  glFogfv(GL_FOG_COLOR, this->mHighlightColor);
955  }
956  else
957  {
958  glFogfv(GL_FOG_COLOR, this->mFogColor);
959  }
960 
961  glFogf(GL_FOG_DENSITY, this->mFogDensity);
962  glHint(GL_FOG_HINT, GL_FASTEST);
964  glEnable(GL_FOG);
965  GLfloat highlight = (GLfloat)this->mHighlight;
966  GLfloat notHighlight = (GLfloat)(!this->mHighlight);
967 
968  if (this->mpResolver)
969  {
970  //std::cout << "Drawing layout." << std::endl;
971  const CLColorDefinition* pBackgroundColor = this->mpResolver->getBackgroundColor();
972  GLfloat red = (GLfloat)(pBackgroundColor->getRed() / 255.0);
973  GLfloat green = (GLfloat)(pBackgroundColor->getGreen() / 255.0);
974  GLfloat blue = (GLfloat)(pBackgroundColor->getBlue() / 255.0);
975  GLfloat alpha = (GLfloat)(pBackgroundColor->getAlpha() / 255.0);
976 
977  if (this->mHighlight == false)
978  {
979  // we have to generate fog on the background ourselfes
980  red = (GLfloat)((red + this->mFogColor[0]) * this->mFogDensity);
981  green = (GLfloat)((green + this->mFogColor[1]) * this->mFogDensity);
982  blue = (GLfloat)((blue + this->mFogColor[2]) * this->mFogDensity);
983  alpha = (GLfloat)((alpha + this->mFogColor[3]) * this->mFogDensity);
984  }
985 
986  glClearColor((GLclampf)red,
987  (GLclampf)green,
988  (GLclampf)blue,
989  (GLclampf)alpha);
990  glClear(GL_COLOR_BUFFER_BIT);
991  glPushMatrix();
992  this->mCurrentAttributes.mX = 0.0;
993  this->mCurrentAttributes.mY = 0.0;
994  this->mCurrentAttributes.mZ = 0.0;
997  const CLReactionGlyph* pRG = NULL;
998  const CLGeneralGlyph* pGG = NULL;
999  const CLReferenceGlyph* pRefG = NULL;
1000  const CLMetabReferenceGlyph* pSRG = NULL;
1001  const CLTextGlyph* pTG = NULL;
1002  std::vector<const CLGraphicalObject*>::iterator it = this->mDrawables.begin(), endit = this->mDrawables.end();
1003  const CLGraphicalObject* pGO = NULL;
1004 // this is needed to highlight or fog certain elements in the diagram
1005  const CCopasiObject* pModelObject = NULL;
1006  std::set<const CLGraphicalObject*>::const_iterator end = this->mHighlightedObjects.end();
1007 
1008  while (it != endit)
1009  {
1010  pGO = *it;
1011  pRG = dynamic_cast<const CLReactionGlyph*>(pGO);
1012  pGG = dynamic_cast<const CLGeneralGlyph*>(pGO);
1013  pSRG = dynamic_cast<const CLMetabReferenceGlyph*>(pGO);
1014  pRefG = dynamic_cast<const CLReferenceGlyph*>(pGO);
1015  pTG = dynamic_cast<const CLTextGlyph*>(pGO);
1016  std::map<const CLGraphicalObject*, const CLStyle*>::const_iterator styleIt = this->mStyleMap.find(pGO);
1017 
1018  if (styleIt == this->mStyleMap.end() || styleIt->second == NULL)
1019  {
1020  ++it;
1021  continue;
1022  }
1023 
1024 // this is needed to highlight or fog certain elements in the diagram
1025  const CLGraphicalObject* pGO2 = NULL;
1026 
1027  if (pSRG == NULL)
1028  {
1029  pModelObject = (pGO)->getModelObject();
1030  pGO2 = pGO;
1031  }
1032  else if (pRefG == NULL)
1033  {
1034  pModelObject = (pGO)->getModelObject();
1035  pGO2 = pGO;
1036  }
1037  else
1038  {
1039  // if we have a species reference glyph, we check if the parent reaction glyph is highlighted and if
1040  // it is we also highlight the species reference glyph
1041  assert((*it)->getObjectParent() != NULL && (*it)->getObjectParent()->getObjectParent() != NULL);
1042  assert(dynamic_cast<const CLGraphicalObject*>((*it)->getObjectParent()->getObjectParent()) != NULL);
1043 
1044  if (pGO->getObjectParent() != NULL &&
1045  pGO->getObjectParent()->getObjectParent() != NULL
1046  )
1047  {
1048  pGO2 = dynamic_cast<const CLGraphicalObject*>(pGO->getObjectParent()->getObjectParent());
1049 
1050  if (pGO2 != NULL)
1051  {
1052  pModelObject = pGO2->getModelObject();
1053  }
1054  }
1055  }
1056 
1057  if (this->mpGlFogCoordfEXT != NULL)
1058  {
1059  if (pModelObject != NULL && this->mHighlightedObjects.find(pGO2) != end)
1060  {
1061  (*(this->mpGlFogCoordfEXT))(highlight);
1062  }
1063  else
1064  {
1065  (*(this->mpGlFogCoordfEXT))(notHighlight);
1066  }
1067  }
1068 
1069  if ((pSRG != NULL && pSRG->getCurve().getNumCurveSegments() != 0))
1070  {
1071  // draw the layout curve
1072  // we need to set the state of the OpenGL state machine
1073  // save the curent state
1074  this->save_current_attributes();
1076 
1077  // only draw the line if the stroke width is a positive value
1078  // greater zero and if there is a stroke color defined
1080  {
1081  bool drawBasepoints = false;
1082 
1083  if (this->mSelection.size() == 1 && (*this->mSelection.begin()) == pSRG)
1084  {
1085  drawBasepoints = true;
1086  }
1087 
1088  this->draw_curve(&pSRG->getCurve(), drawBasepoints);
1089  }
1090 
1092 
1093  // if the curve is the only selected item, we draw the base points,
1094  // otherwise we only draw the selection frame
1095  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1096  {
1097  CLBoundingBox* pBB = getCurveBoundingBox(&pSRG->getCurve());
1098  this->drawSelectionBox(pBB->getPosition().getX(), pBB->getPosition().getY(),
1099  pBB->getDimensions().getWidth(), pBB->getDimensions().getHeight(), this->mSelection.size() == 1);
1100  delete pBB;
1101  }
1102  }
1103  else if ((pRefG != NULL && pRefG->getCurve().getNumCurveSegments() != 0))
1104  {
1105  // draw the layout curve
1106  // we need to set the state of the OpenGL state machine
1107  // save the curent state
1108  this->save_current_attributes();
1110 
1111  // only draw the line if the stroke width is a positive value
1112  // greater zero and if there is a stroke color defined
1114  {
1115  bool drawBasepoints = false;
1116 
1117  if (this->mSelection.size() == 1 && (*this->mSelection.begin()) == pRefG)
1118  {
1119  drawBasepoints = true;
1120  }
1121 
1122  this->draw_curve(&pRefG->getCurve(), drawBasepoints);
1123  }
1124 
1126 
1127  // if the curve is the only selected item, we draw the base points,
1128  // otherwise we only draw the selection frame
1129  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1130  {
1131  CLBoundingBox* pBB = getCurveBoundingBox(&pRefG->getCurve());
1132  this->drawSelectionBox(pBB->getPosition().getX(), pBB->getPosition().getY(),
1133  pBB->getDimensions().getWidth(), pBB->getDimensions().getHeight(), this->mSelection.size() == 1);
1134  delete pBB;
1135  }
1136  }
1137  else if (pRG != NULL && pRG->getCurve().getNumCurveSegments() != 0)
1138  {
1139  // draw the layout curve
1140  // we need to set the state of the OpenGL state machine
1141  // save the curent state
1142  this->save_current_attributes();
1144 
1145  // only do something if the stroke width is a positive value
1146  // greater 0 and if there is a stroke color defined
1148  {
1149  // set the state
1150  bool drawBasepoints = false;
1151 
1152  if (this->mSelection.size() == 1 && (*this->mSelection.begin()) == pRG)
1153  {
1154  drawBasepoints = true;
1155  }
1156 
1157  this->draw_curve(&pRG->getCurve(), drawBasepoints);
1158  // reset the original state
1159  }
1160 
1162 
1163  // if the curve is the only selected item, we draw the base points,
1164  // otherwise we only draw the selection frame
1165  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1166  {
1167  CLBoundingBox* pBB = getCurveBoundingBox(&pRG->getCurve());
1168  this->drawSelectionBox(pBB->getPosition().getX(), pBB->getPosition().getY(),
1169  pBB->getDimensions().getWidth(), pBB->getDimensions().getHeight(), this->mSelection.size() == 1);
1170  delete pBB;
1171  }
1172  }
1173  else if (pGG != NULL && pGG->getCurve().getNumCurveSegments() != 0)
1174  {
1175  // draw the layout curve
1176  // we need to set the state of the OpenGL state machine
1177  // save the curent state
1178  this->save_current_attributes();
1180 
1181  // only do something if the stroke width is a positive value
1182  // greater 0 and if there is a stroke color defined
1184  {
1185  // set the state
1186  bool drawBasepoints = false;
1187 
1188  if (this->mSelection.size() == 1 && (*this->mSelection.begin()) == pGG)
1189  {
1190  drawBasepoints = true;
1191  }
1192 
1193  this->draw_curve(&pGG->getCurve(), drawBasepoints);
1194  // reset the original state
1195  }
1196 
1198 
1199  // if the curve is the only selected item, we draw the base points,
1200  // otherwise we only draw the selection frame
1201  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1202  {
1203  CLBoundingBox* pBB = getCurveBoundingBox(&pGG->getCurve());
1204  this->drawSelectionBox(pBB->getPosition().getX(), pBB->getPosition().getY(),
1205  pBB->getDimensions().getWidth(), pBB->getDimensions().getHeight(), this->mSelection.size() == 1);
1206  delete pBB;
1207  }
1208  }
1209  else if (pTG != NULL)
1210  {
1211  //std::cout << "Drawing CLText*Glyph: " << pTG->getId() << std::endl;
1212  std::map<const CLTextGlyph*, const CLTextTextureSpec*>::const_iterator pos = this->mTextGlyphMap.find(pTG);
1213  assert(pos != this->mTextGlyphMap.end());
1214 
1215  if (pos->second != NULL && pos->second->mTextureName != 0)
1216  {
1217  //std::cout << "Texture for text glyph found." << std::endl;
1218  // in order to position text glyphs corectly, we have to move them up by their mAscent
1219  CLBoundingBox bb = pTG->getBoundingBox();
1220  CLPoint* pP = &bb.getPosition();
1221  bb.setPosition(*pP);
1222  this->draw_text(styleIt->second, &bb, pos->second);
1223 
1224  // draw the selection frame
1225  // if it is the only selected element, we also draw the resize handles
1226  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1227  {
1228  // we need to adjust the bounding box the same way we adjust the text glyphs
1229  this->drawSelectionBox(bb.getPosition().getX(), bb.getPosition().getY() + pos->second->mAscent,
1230  bb.getDimensions().getWidth(), bb.getDimensions().getHeight(), this->mSelection.size() == 1);
1231  }
1232  }
1233  }
1234  else
1235  {
1236  const CLBoundingBox* pBB = &pGO->getBoundingBox();
1237  this->draw_object(styleIt->second, pBB);
1238 
1239  // draw the selection frame
1240  // if it is the only selected element, we also draw the resize handles
1241  if (this->mSelection.find(const_cast<CLGraphicalObject*>(pGO)) != this->mSelection.end())
1242  {
1243  this->drawSelectionBox(pBB->getPosition().getX(), pBB->getPosition().getY(),
1244  pBB->getDimensions().getWidth(), pBB->getDimensions().getHeight(), this->mSelection.size() == 1);
1245  }
1246  }
1247 
1248  ++it;
1249  }
1250 
1251  // flush the GL queue
1252  glPopMatrix();
1253  // draw the selection box
1254  this->draw_selection_box();
1255  glFlush();
1256  //std::cout << "Drawing finished." << std::endl << std::endl;
1257  }
1258 
1259  glDisable(GL_FOG);
1260 }
void draw_object(const CLStyle *pStyle, const CLBoundingBox *pBB)
GLfloat mHighlightColor[4]
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
std::vector< const CLGraphicalObject * > mDrawables
std::set< CLGraphicalObject * > mSelection
const CLBoundingBox & getBoundingBox() const
void setPosition(const CLPoint &p)
Definition: CLBase.h:272
static void extract_group_attributes(const CLStyle *pStyle, CLGroupAttributes *attributes)
unsigned char getBlue() const
std::map< const CLTextGlyph *, const CLTextTextureSpec * > mTextGlyphMap
void draw_text(const CLStyle *pStyle, const CLBoundingBox *pBB, const CLTextTextureSpec *pTexture)
CLGroupAttributes mCurrentAttributes
static void drawSelectionBox(double x, double y, double width, double height, bool drawHandles=false)
std::set< const CLGraphicalObject * > mHighlightedObjects
#define GL_FOG_COORD_SRC
Definition: glext.h:383
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
const CLPoint & getPosition() const
Definition: CLBase.h:265
unsigned char getGreen() const
unsigned char getRed() const
static CLBoundingBox * getCurveBoundingBox(const CLCurve *pCurve)
unsigned char getAlpha() const
const CLColorDefinition * getBackgroundColor() const
#define GL_FOG_COORD
Definition: glext.h:384
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
CCopasiObject * getModelObject() const
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
void(* mpGlFogCoordfEXT)(GLfloat)
void initialize_gl_extension_functions()
CLRenderResolver * mpResolver
void draw_selection_box() const
const CLCurve & getCurve() const
size_t getNumCurveSegments() const
Definition: CLCurve.h:168
CCopasiContainer * getObjectParent() const
void draw_curve(const CLCurve *pCurve, bool drawBasepoints=false)
const CLDimensions & getDimensions() const
Definition: CLayout.h:76
std::map< const CLGraphicalObject *, const CLStyle * > mStyleMap
std::string mStroke
void CLLayoutRenderer::draw_line ( size_t  numPoints,
GLdouble *  pData 
)
protected

Method to draw a line made up of a set of points.

Definition at line 3075 of file CLLayoutRenderer.cpp.

References draw_cap(), draw_line_segment(), mCurrentAttributes, mLinestippleMap, CLLineStippleTexture::mPatternLength, CLGroupAttributes::mStrokeDasharray, CLGroupAttributes::mStrokeWidth, CLLineStippleTexture::mTextureLength, CLLineStippleTexture::mTextureName, and segment_data().

Referenced by draw_curve(), and draw_datapoints().

3076 {
3077  // a line has to have more than one point
3078  if (numPoints > 1)
3079  {
3080  // create the texture for line stippling
3081  const CLLineStippleTexture* pTexture = NULL;
3082  std::map<const std::vector<unsigned int>, const CLLineStippleTexture*>::const_iterator pos = this->mLinestippleMap.find(this->mCurrentAttributes.mStrokeDasharray);
3083 
3084  if (pos != this->mLinestippleMap.end())
3085  {
3086  pTexture = pos->second;
3087  }
3088 
3089  GLfloat* pTextureCoordinates = NULL;
3090  GLdouble* pOrigData = pData;
3091  size_t iMax = numPoints;
3092 
3093  if (pTexture != NULL)
3094  {
3095  // segment the
3096  // datapoints into pieces that fit the texture pattern
3097  // and create the texture coordinates
3098  std::vector<simple_point> v;
3099  // we need at least numPoints elements in the vector
3100  v.reserve(numPoints);
3101  this->segment_data(pTexture->mPatternLength, (double)pTexture->mPatternLength / (double)pTexture->mTextureLength, numPoints, pData, v);
3102 
3103  if (v.size() != numPoints)
3104  {
3105  iMax = (unsigned int)v.size();
3106  // we have to create a new dataset
3107  pData = new GLdouble[3 * iMax];
3108  pTextureCoordinates = new GLfloat[iMax];
3109  std::vector<simple_point>::const_iterator it = v.begin(), endit = v.end();
3110  unsigned int index = 0;
3111  unsigned int index2 = 0;
3112 
3113  while (it != endit)
3114  {
3115  pData[index++] = it->mX;
3116  pData[index++] = it->mY;
3117  pData[index++] = it->mZ;
3118  pTextureCoordinates[index2++] = (GLfloat)it->mS;
3119  ++it;
3120  }
3121  }
3122  else
3123  {
3124  // create an array for the texture coordinates
3125  pTextureCoordinates = new GLfloat[iMax];
3126  std::vector<simple_point>::const_iterator it = v.begin(), endit = v.end();
3127  unsigned int index = 0;
3128 
3129  while (it != endit)
3130  {
3131  pTextureCoordinates[index++] = (GLfloat)it->mS;
3132  ++it;
3133  }
3134  }
3135 
3136  if (pTexture->mTextureName != 0)
3137  {
3138  glBindTexture(GL_TEXTURE_1D, pTexture->mTextureName);
3139  // enable 1D texturing
3140  glEnable(GL_TEXTURE_1D);
3141  }
3142  }
3143 
3144  unsigned int i;
3145  // the loop does not go to the very last point, but stops one before that
3146  --iMax;
3147  unsigned int index = 0;
3148 
3149  for (i = 0; i < iMax; ++i)
3150  {
3151  if (pTextureCoordinates)
3152  {
3153  draw_line_segment(pData[index], pData[index + 1], pData[index + 2], pData[index + 3], pData[index + 4], pData[index + 5], mCurrentAttributes.mStrokeWidth, true, 0.0, pTextureCoordinates[i + 1]);
3154  }
3155  else
3156  {
3157  draw_line_segment(pData[index], pData[index + 1], pData[index + 2], pData[index + 3], pData[index + 4], pData[index + 5], mCurrentAttributes.mStrokeWidth);
3158  }
3159 
3160  index += 3;
3161 
3162  // don't draw a cap after the last segment
3163  if (i != iMax - 1)
3164  {
3165  draw_cap(pData[index - 3], pData[index - 2], pData[index - 1], pData[index], pData[index + 1], pData[index + 2], pData[index + 3], pData[index + 4], pData[index + 5], mCurrentAttributes.mStrokeWidth);
3166  }
3167  }
3168 
3169  // if we created new datapoints, we have to delete them again
3170  if (pOrigData != pData)
3171  {
3172  delete[] pData;
3173  pData = pOrigData;
3174  }
3175 
3176  // delete any texture coordinates we have created
3177  if (pTextureCoordinates != NULL)
3178  {
3179  delete[] pTextureCoordinates;
3180  glDisable(GL_TEXTURE_1D);
3181  }
3182  }
3183 }
void draw_line_segment(double x1, double y1, double z1, double x2, double y2, double z2, double line_width, bool texture=false, double s1=0.0, double s2=0.0)
unsigned int mPatternLength
CLGroupAttributes mCurrentAttributes
void draw_cap(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3, double stroke_width)
std::map< const std::vector< unsigned int >, const CLLineStippleTexture * > mLinestippleMap
std::vector< unsigned int > mStrokeDasharray
unsigned int mTextureLength
void segment_data(double length, double ratio, size_t numPoints, GLdouble *pData, std::vector< simple_point > &v)
void CLLayoutRenderer::draw_line_segment ( double  x1,
double  y1,
double  z1,
double  x2,
double  y2,
double  z2,
double  line_width,
bool  texture = false,
double  s1 = 0.0,
double  s2 = 0.0 
)
protected

Method that draws a line with the given start and end points. All the other parameter like color, linewidth etc. have to be set before.

Definition at line 265 of file CLLayoutRenderer.cpp.

References ALMOST_ZERO.

Referenced by draw_line().

266 {
267  // calculate the 4 points of the rectangle considering the line width
268  // actually the correct thing to do would be to draw a tube, but right now
269  // this is takes to many ressources, so we draw a rectangle and use the same
270  // mapping as for the line endings.
271  // calculate the direction vector
272  double vx1 = x2 - x1;
273  double vy1 = y2 - y1;
274  double vz1 = z2 - z1;
275  double length = sqrt(vx1 * vx1 + vy1 * vy1 + vz1 * vz1);
276 
277  // calculate the normal to this vector
278  double vx2 = 0.0;
279  double vy2 = 0.0;
280  double vz2 = 0.0;
281  double half_width = line_width / 2.0;
282 
283  if (fabs(vx1) < ALMOST_ZERO && vz1 < ALMOST_ZERO)
284  {
285  // scale by the line_width
286  vx2 = -vy1 / length * half_width;
287  vy2 = 0.0;
288  vz2 = 0.0;
289  }
290  else
291  {
292  // scale by the line_width
293  double normY = vy1 / length;
294  vx2 = -normY * vx1 / length * half_width;
295  vy2 = (1 - normY * normY) * half_width;
296  vz2 = -normY * vz1 / length * half_width;
297  double normLength = half_width / sqrt(vx2 * vx2 + vy2 * vy2 + vz2 * vz2);
298  vx2 *= normLength;
299  vy2 *= normLength;
300  vz2 *= normLength;
301  }
302 
303  // calculate the 4 points
304  GLfloat* pDatapoints = new GLfloat[12];
305  pDatapoints[0] = (GLfloat)(x1 + vx2);
306  pDatapoints[1] = (GLfloat)(y1 + vy2);
307  pDatapoints[2] = (GLfloat)(z1 + vz2);
308  pDatapoints[3] = (GLfloat)(x1 - vx2);
309  pDatapoints[4] = (GLfloat)(y1 - vy2);
310  pDatapoints[5] = (GLfloat)(z1 - vz2);
311  pDatapoints[6] = (GLfloat)(x2 + vx2);
312  pDatapoints[7] = (GLfloat)(y2 + vy2);
313  pDatapoints[8] = (GLfloat)(z2 + vz2);
314  pDatapoints[9] = (GLfloat)(x2 - vx2);
315  pDatapoints[10] = (GLfloat)(y2 - vy2);
316  pDatapoints[11] = (GLfloat)(z2 - vz2);
317  // enable the line stippling texture if necessary
318  GLfloat* pTextureCoordinates = NULL;
319 
320  if (texture)
321  {
322  pTextureCoordinates = new GLfloat[4];
323  pTextureCoordinates[0] = (GLfloat)s1;
324  pTextureCoordinates[1] = (GLfloat)s1;
325  pTextureCoordinates[2] = (GLfloat)s2;
326  pTextureCoordinates[3] = (GLfloat)s2;
327  // create an array for texture coordinates
328  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
329  glTexCoordPointer(1, GL_FLOAT, 0, pTextureCoordinates);
330  }
331 
332  // just draw as a triangle strip
333  glEnableClientState(GL_VERTEX_ARRAY);
334  glVertexPointer(3, GL_FLOAT, 0, pDatapoints);
335  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
336  glDisableClientState(GL_VERTEX_ARRAY);
337 
338  // disable the line stippleling texture if necessary
339  if (texture)
340  {
341  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
342  delete[] pTextureCoordinates;
343  }
344 
345  delete[] pDatapoints;
346 }
static const double ALMOST_ZERO
void CLLayoutRenderer::draw_object ( const CLStyle pStyle,
const CLBoundingBox pBB 
)
protected

Method to draw an arbitrary object specified by it's bounding box and the style with which it should be drawn.

Definition at line 1337 of file CLLayoutRenderer.cpp.

References draw_group(), and CLStyle::getGroup().

Referenced by draw_layout().

1338 {
1339  this->draw_group(pStyle->getGroup(), pBB);
1340 }
const CLGroup * getGroup() const
Definition: CLStyle.cpp:91
void draw_group(const CLGroup *pGroup, const CLBoundingBox *pBB)
void CLLayoutRenderer::draw_polygon ( const CLPolygon pPolygon,
const CLBoundingBox pBB 
)
protected

Method to draw a render polygon object.

Definition at line 1793 of file CLLayoutRenderer.cpp.

References CLRenderCubicBezier::basePoint1_X(), CLRenderCubicBezier::basePoint1_Y(), CLRenderCubicBezier::basePoint1_Z(), CLRenderCubicBezier::basePoint2_X(), CLRenderCubicBezier::basePoint2_Y(), CLRenderCubicBezier::basePoint2_Z(), calculate_cubicbezier(), convert_to_absolute(), draw_datapoints(), extract_2d_attributes(), CLPolygon::getElement(), CLPolygon::getNumElements(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), mCurrentAttributes, simple_point::mX, simple_point::mY, simple_point::mZ, NUM_BEZIER_POINTS, restore_current_attributes(), save_current_attributes(), CLRenderPoint::x(), CLRenderPoint::y(), and CLRenderPoint::z().

Referenced by draw_group().

1794 {
1795  /*
1796  * Old code to draw the polygon when it consists of only straight lines.
1797  size_t numPoints=pPolygon->getNumElements()+1;
1798  if(numPoints>1)
1799  {
1800  // store and change the attributes
1801  this->save_current_attributes();
1802  CLLayoutRenderer::extract_2d_attributes(pPolygon,&mCurrentAttributes);
1803  // create the data points
1804  GLdouble* pData=new GLdouble[3*numPoints];
1805  size_t i,iMax=numPoints-1;
1806  CLPoint p;
1807  const CLRenderPoint* pP;
1808  size_t index=0;
1809  for(i=0;i<iMax;++i)
1810  {
1811  pP=pPolygon->getElement(i);
1812  assert(pP);
1813  p=CLLayoutRenderer::convert_to_absolute(pP,pBB);
1814  pData[index++]=p.getX();
1815  pData[index++]=p.getY();
1816  pData[index++]=p.getZ();
1817  }
1818  pData[index++]=pData[0];
1819  pData[index++]=pData[1];
1820  pData[index]=pData[2];
1821  */
1822 
1823  // the first one has to be a point
1824  // store and change the attributes
1825  if (pPolygon->getNumElements() > 1)
1826  {
1827  this->save_current_attributes();
1829  const CLRenderPoint* pStart = pPolygon->getElement(0);
1830  CLRenderPoint end, bp1, bp2;
1831  CLPoint p1 = convert_to_absolute(pStart, pBB);
1832  CLPoint p2, p3, p4;
1833  std::vector<simple_point> v;
1834  // there are going to be at least iMax elements in the vector
1835  size_t i, iMax = pPolygon->getNumElements();
1836  v.reserve(iMax);
1837  simple_point p;
1838  p.mX = p1.getX();
1839  p.mY = p1.getY();
1840  p.mZ = p1.getZ();
1841  v.push_back(p);
1842  GLdouble* pData = NULL;
1843  const CLRenderPoint* pP;
1844  const CLRenderCubicBezier* pCB;
1845 
1846  for (i = 1; i < iMax; ++i)
1847  {
1848  pP = pPolygon->getElement(i);
1849  pCB = dynamic_cast<const CLRenderCubicBezier*>(pP);
1850 
1851  if (pCB != NULL)
1852  {
1853  end = CLRenderPoint(pCB->x(), pCB->y(), pCB->z());
1854  bp1 = CLRenderPoint(pCB->basePoint1_X(), pCB->basePoint1_Y(), pCB->basePoint1_Z());
1855  bp2 = CLRenderPoint(pCB->basePoint2_X(), pCB->basePoint2_Y(), pCB->basePoint2_Z());
1856  p2 = convert_to_absolute(&end, pBB);
1857  p3 = convert_to_absolute(&bp1, pBB);
1858  p4 = convert_to_absolute(&bp2, pBB);
1859  pData = new GLdouble[3 * NUM_BEZIER_POINTS];
1861  p3.getX(), p3.getY(), p3.getZ(),
1862  p4.getX(), p4.getY(), p4.getZ(),
1863  p2.getX(), p2.getY(), p2.getZ(),
1864  NUM_BEZIER_POINTS, pData);
1865  size_t j;
1866  size_t index = 0;
1867 
1868  for (j = 0; j < NUM_BEZIER_POINTS; ++j)
1869  {
1870  p.mX = pData[index++];
1871  p.mY = pData[index++];
1872  p.mZ = pData[index++];
1873  v.push_back(p);
1874  }
1875 
1876  delete[] pData;
1877  }
1878  else
1879  {
1880  end = CLRenderPoint(pP->x(), pP->y(), pP->z());
1881  p2 = convert_to_absolute(&end, pBB);
1882  p.mX = p2.getX();
1883  p.mY = p2.getY();
1884  p.mZ = p2.getZ();
1885  v.push_back(p);
1886  }
1887 
1888  // this end is the next start
1889  p1 = p2;
1890  }
1891 
1892  iMax = v.size();
1893 
1894  if (iMax > 1)
1895  {
1896  pData = new GLdouble[3 * (iMax + 1)];
1897  size_t index = 0;
1898  const simple_point* pSimple = NULL;
1899 
1900  for (i = 0; i < iMax; ++i)
1901  {
1902  pSimple = &v[i];
1903  pData[index++] = pSimple->mX;
1904  pData[index++] = pSimple->mY;
1905  pData[index++] = pSimple->mZ;
1906  }
1907 
1908  pData[index++] = pData[0];
1909  pData[index++] = pData[1];
1910  pData[index] = pData[2];
1911  // draw the polygon
1912  this->draw_datapoints(pData, iMax + 1, pBB, true);
1913  delete[] pData;
1914  }
1915 
1916  // restore the attributes
1918  }
1919 }
static void calculate_cubicbezier(double sx, double sy, double sz, double p1x, double p1y, double p1z, double p2x, double p2y, double p2z, double ex, double ey, double ez, unsigned int numPoints, GLdouble *pData)
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
const CLRelAbsVector & basePoint1_X() const
const CLRelAbsVector & basePoint2_Y() const
const CLRelAbsVector & z() const
void draw_datapoints(GLdouble *pData, size_t numPoints, const CLBoundingBox *pBB, bool doTesselation=false, float xOffset=0.0, float yOffset=0.0, float zOffset=0.0)
const CLRelAbsVector & basePoint2_Z() const
CLRenderPoint * getElement(size_t index)
Definition: CLPolygon.cpp:145
static const CLPoint convert_to_absolute(const CLRenderPoint *pRenderPoint, const CLBoundingBox *pBB)
static void extract_2d_attributes(const CLGraphicalPrimitive2D *pObject, CLGroupAttributes *attributes)
const CLRelAbsVector & basePoint2_X() const
CLGroupAttributes mCurrentAttributes
const CLRelAbsVector & y() const
size_t getNumElements() const
Definition: CLPolygon.cpp:100
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
Definition: CLBase.h:54
static const unsigned int NUM_BEZIER_POINTS
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
const CLRelAbsVector & basePoint1_Z() const
const CLRelAbsVector & x() const
const CLRelAbsVector & basePoint1_Y() const
void CLLayoutRenderer::draw_rectangle ( const CLRectangle pRectangle,
const CLBoundingBox pBB 
)
protected

Method to draw a render rectangle object.

Definition at line 1924 of file CLLayoutRenderer.cpp.

References convert_to_absolute(), draw_datapoints(), extract_2d_attributes(), CLRelAbsVector::getAbsoluteValue(), CLBoundingBox::getDimensions(), CLRectangle::getHeight(), CLDimensions::getHeight(), CLRectangle::getRadiusX(), CLRectangle::getRadiusY(), CLRelAbsVector::getRelativeValue(), CLRectangle::getWidth(), CLDimensions::getWidth(), CLRectangle::getX(), CLRectangle::getY(), CLRectangle::getZ(), mCurrentAttributes, NUM_CORNER_SEGMENTS, restore_current_attributes(), and save_current_attributes().

Referenced by draw_group().

1925 {
1926  // store and change the attributes
1927  this->save_current_attributes();
1929  // draw the rectangle
1930  // first we calculate the points of the rectangle
1931  CLRenderPoint rp(pRectangle->getX(), pRectangle->getY(), pRectangle->getZ());
1933  CLRelAbsVector v = pRectangle->getWidth();
1934  double width = v.getAbsoluteValue() + (v.getRelativeValue() / 100.0) * pBB->getDimensions().getWidth();
1935  v = pRectangle->getHeight();
1936  double height = v.getAbsoluteValue() + (v.getRelativeValue() / 100.0) * pBB->getDimensions().getHeight();
1937  v = pRectangle->getRadiusX();
1938  double rx = v.getAbsoluteValue() + (v.getRelativeValue() / 100.0) * width;
1939  v = pRectangle->getRadiusY();
1940  double ry = v.getAbsoluteValue() + (v.getRelativeValue() / 100.0) * height;
1941 
1942  // make sure rx and ry are not greater than half the width or height of the
1943  // rectangle.
1944  if (rx > width / 2.0) rx = width / 2.0;
1945 
1946  if (ry > height / 2.0) ry = height / 2.0;
1947 
1948  size_t numPoints = 4;
1949 
1950  if (rx > 0.0 && ry > 0.0)
1951  {
1952  // we have four corners
1953  // plus 4 points for the straight lines
1954  numPoints = 4 * (NUM_CORNER_SEGMENTS + 1);
1955  }
1956 
1957  // we need to reserve space for all data points and each point has three
1958  // values
1959  // we add an additonal data point to close the loop
1960  GLdouble* pData = new GLdouble[(numPoints + 1) * 3];
1961  double x = p.getX();
1962  double y = p.getY();
1963  double z = p.getZ();
1964  // now we fill the data array
1965  size_t index = 0;
1966 
1967  if (rx > 0.0 && ry > 0.0)
1968  {
1969  size_t i = 0;
1970  pData[i++] = 0.0;
1971  pData[i++] = ry;
1972  pData[i++] = 0.0;
1973  pData[i++] = 0.0;
1974  pData[i++] = height - ry;
1975  pData[i++] = 0.0;
1976  i += (NUM_CORNER_SEGMENTS - 1) * 3;
1977  pData[i++] = rx;
1978  pData[i++] = height;
1979  pData[i++] = 0.0;
1980  pData[i++] = width - rx;
1981  pData[i++] = height;
1982  pData[i++] = 0.0;
1983  i += (NUM_CORNER_SEGMENTS - 1) * 3;
1984  pData[i++] = width;
1985  pData[i++] = height - ry;
1986  pData[i++] = 0.0;
1987  pData[i++] = width;
1988  pData[i++] = ry;
1989  pData[i++] = 0.0;
1990  i += (NUM_CORNER_SEGMENTS - 1) * 3;
1991  pData[i++] = width - rx;
1992  pData[i++] = 0.0;
1993  pData[i++] = 0.0;
1994  pData[i++] = rx;
1995  pData[i++] = 0.0;
1996  pData[i] = 0.0;
1997  double delta = M_PI / (2.0 * NUM_CORNER_SEGMENTS);
1998  double phi = delta;
1999  double dx, dy, dx_inv, dy_inv;
2000  index = 0;
2001 
2002  for (i = 0; i < NUM_CORNER_SEGMENTS - 1; ++i)
2003  {
2004  index = (2 + i) * 3;
2005  dx = rx * sin(phi);
2006  dy = ry * cos(phi);
2007  dx_inv = rx * sin(M_PI / 2.0 - phi);
2008  dy_inv = ry * cos(M_PI / 2.0 - phi);
2009  // the first corner is mirrored, so we switch dx and dy
2010  pData[index] = rx - dx_inv;
2011  pData[index + 1] = height - ry + dy_inv;
2012  pData[index + 2] = 0.0;
2013  // the second corner is actually the one, we calculate
2014  index += (NUM_CORNER_SEGMENTS + 1) * 3;
2015  pData[index] = width - rx + dx;
2016  pData[index + 1] = height - ry + dy;
2017  pData[index + 2] = 0.0;
2018  // third corner is again mirrored
2019  index += (NUM_CORNER_SEGMENTS + 1) * 3;
2020  pData[index] = width - rx + dx_inv;
2021  pData[index + 1] = ry - dy_inv;
2022  pData[index + 2] = 0.0;
2023  // the fourth corner
2024  index += (NUM_CORNER_SEGMENTS + 1) * 3;
2025  pData[index] = rx - dx;
2026  pData[index + 1] = ry - dy;
2027  pData[index + 2] = 0.0;
2028  phi += delta;
2029  }
2030  }
2031  else
2032  {
2033  // first corner
2034  pData[0] = 0.0;
2035  pData[1] = 0.0;
2036  pData[2] = 0.0;
2037  // second corner
2038  pData[3] = 0.0;
2039  pData[4] = height;
2040  pData[5] = 0.0;
2041  // third corner
2042  pData[6] = width;
2043  pData[7] = height;
2044  pData[8] = 0.0;
2045  // fourth corner
2046  pData[9] = width;
2047  pData[10] = 0.0;
2048  pData[11] = 0.0;
2049  }
2050 
2051  index = 3 * numPoints;
2052  // we close the loop
2053  pData[index++] = pData[0];
2054  pData[index++] = pData[1];
2055  pData[index] = pData[2];
2056  this->draw_datapoints(pData, numPoints + 1, pBB, false, (GLfloat)x, (GLfloat)y, (GLfloat)z);
2057  // delete the data again
2058  delete[] pData;
2059  //
2060  // restore the attributes
2062 }
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const CLRelAbsVector & getRadiusY() const
const CLRelAbsVector & getWidth() const
double getRelativeValue() const
void draw_datapoints(GLdouble *pData, size_t numPoints, const CLBoundingBox *pBB, bool doTesselation=false, float xOffset=0.0, float yOffset=0.0, float zOffset=0.0)
static const CLPoint convert_to_absolute(const CLRenderPoint *pRenderPoint, const CLBoundingBox *pBB)
static void extract_2d_attributes(const CLGraphicalPrimitive2D *pObject, CLGroupAttributes *attributes)
CLGroupAttributes mCurrentAttributes
static const unsigned int NUM_CORNER_SEGMENTS
const CLRelAbsVector & getX() const
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const CLRelAbsVector & getY() const
const CLRelAbsVector & getRadiusX() const
const CLRelAbsVector & getHeight() const
Definition: CLBase.h:54
double getAbsoluteValue() const
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
const CLRelAbsVector & getZ() const
void CLLayoutRenderer::draw_selection_box ( ) const
protected

draws the selection box if there is one

Definition at line 6528 of file CLLayoutRenderer.cpp.

References CLBoundingBox::getDimensions(), CLDimensions::getHeight(), CLBoundingBox::getPosition(), CLDimensions::getWidth(), CLPoint::getX(), CLPoint::getY(), mH, mpSelectionBox, mW, mX, mY, and mZoomFactor.

Referenced by draw_layout().

6529 {
6530  if (this->mpSelectionBox != NULL)
6531  {
6532  // draw four semi transparent rectangles around the
6533  // bounding box
6534  double width = this->mW / this->mZoomFactor;
6535  double height = this->mH / this->mZoomFactor;
6536  double lx = this->mpSelectionBox->getPosition().getX();
6537  double ly = this->mpSelectionBox->getPosition().getY();
6538  double rx = lx + this->mpSelectionBox->getDimensions().getWidth();
6539  double ry = ly + this->mpSelectionBox->getDimensions().getHeight();
6540  glColor4f(0.5, 0.5, 0.5, 0.5);
6541  // top
6542  glBegin(GL_POLYGON);
6543  glVertex3d(this->mX, this->mY, 0.1);
6544  glVertex3d(this->mX + width, this->mY, 0.1);
6545  glVertex3d(this->mX + width, ly, 0.1);
6546  glVertex3d(this->mX, ly, 0.1);
6547  glEnd();
6548  // bottom
6549  glBegin(GL_POLYGON);
6550  glVertex3d(this->mX, ry, 0.1);
6551  glVertex3d(this->mX + width, ry, 0.1);
6552  glVertex3d(this->mX + width, this->mY + height, 0.1);
6553  glVertex3d(this->mX, this->mY + height, 0.1);
6554  glEnd();
6555  // left
6556  glBegin(GL_POLYGON);
6557  glVertex3d(this->mX, ly, 0.1);
6558  glVertex3d(lx, ly, 0.1);
6559  glVertex3d(lx, ry, 0.1);
6560  glVertex3d(this->mX, ry, 0.1);
6561  glEnd();
6562  // right
6563  glBegin(GL_POLYGON);
6564  glVertex3d(rx, ly, 0.1);
6565  glVertex3d(this->mX + width, ly, 0.1);
6566  glVertex3d(this->mX + width, ry, 0.1);
6567  glVertex3d(rx, ry, 0.1);
6568  glEnd();
6569  }
6570 }
CLBoundingBox * mpSelectionBox
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const CLPoint & getPosition() const
Definition: CLBase.h:265
const C_FLOAT64 & getY() const
Definition: CLBase.h:84
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
void CLLayoutRenderer::draw_text ( const CLStyle pStyle,
const CLBoundingBox pBB,
const CLTextTextureSpec pTexture 
)
protected

Method to draw a text object specified by it's bounding box and the style with which it should be drawn as well as the actual string.

Definition at line 1267 of file CLLayoutRenderer.cpp.

References CLText::ANCHOR_BOTTOM, CLText::ANCHOR_END, CLText::ANCHOR_MIDDLE, extract_1d_attributes(), extract_text_attributes(), CLBoundingBox::getDimensions(), CLStyle::getGroup(), CLDimensions::getHeight(), CLDimensions::getWidth(), mCurrentAttributes, CLGroupAttributes::mStroke, CLGroupAttributes::mTextAnchor, CLGroupAttributes::mVTextAnchor, restore_current_attributes(), and save_current_attributes().

Referenced by draw_group(), draw_layout(), and draw_text().

1268 {
1269  // set the attributes
1270  this->save_current_attributes();
1271  // for text elements, only the 1d attributes and the special text
1272  // attributes are relevant
1275 
1276  // we only draw the text if there is a stroke color to draw it with
1277  if (!mCurrentAttributes.mStroke.empty() && mCurrentAttributes.mStroke != "none")
1278  {
1279  // with the new interpretation of the text alignment attributes,
1280  // we have to specify different offset attributes
1281  // if the horizontal laignment is middle, we specify the middle of the box
1282  // as x offset and if the alignment is end, we specify the end as the x offset
1283  // likewise for the vertical alignment and the y offset
1284  double xOffset = 0.0;
1285  double yOffset = 0.0;
1286 
1288  {
1289  xOffset = pBB->getDimensions().getWidth() * 0.5;;
1290  }
1292  {
1293  xOffset = pBB->getDimensions().getWidth();
1294  }
1295 
1297  {
1298  yOffset = pBB->getDimensions().getHeight() * 0.5;
1299  }
1301  {
1302  yOffset = pBB->getDimensions().getHeight();
1303  }
1304 
1305  this->draw_text(pTexture, xOffset, yOffset, 0.0, pBB);
1306  }
1307 
1308  //restore the attributes
1310 }
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
CLText::TEXT_ANCHOR mTextAnchor
void draw_text(const CLStyle *pStyle, const CLBoundingBox *pBB, const CLTextTextureSpec *pTexture)
CLGroupAttributes mCurrentAttributes
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
const CLGroup * getGroup() const
Definition: CLStyle.cpp:91
static void extract_1d_attributes(const CLGraphicalPrimitive1D *pObject, CLGroupAttributes *attributes)
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
static void extract_text_attributes(const T *pObject, CLGroupAttributes *attributes)
CLText::TEXT_ANCHOR mVTextAnchor
std::string mStroke
void CLLayoutRenderer::draw_text ( const CLText pText,
const CLBoundingBox pBB 
)
protected

Method to draw a render text object.

Definition at line 1520 of file CLLayoutRenderer.cpp.

References draw_text(), extract_1d_attributes(), extract_text_attributes(), CLRelAbsVector::getAbsoluteValue(), CLDimensions::getDepth(), CLBoundingBox::getDimensions(), CLDimensions::getHeight(), CLRelAbsVector::getRelativeValue(), CLDimensions::getWidth(), CLText::getX(), CLText::getY(), CLText::getZ(), CLText::isSetText(), mCurrentAttributes, mTextMap, restore_current_attributes(), and save_current_attributes().

1521 {
1522  if (pText->isSetText())
1523  {
1524  // set the attributes
1525  this->save_current_attributes();
1526  // for text elements, only the 1d attributes and the special text
1527  // attributes are relevant
1530  // draw the string
1531  double x = pText->getX().getAbsoluteValue() + pText->getX().getRelativeValue() / 100.0 * pBB->getDimensions().getWidth();
1532  double y = pText->getY().getAbsoluteValue() + pText->getY().getRelativeValue() / 100.0 * pBB->getDimensions().getHeight();
1533  double z = pText->getZ().getAbsoluteValue() + pText->getZ().getRelativeValue() / 100.0 * pBB->getDimensions().getDepth();
1534  std::map<const CLText*, const CLTextTextureSpec*>::const_iterator pos = this->mTextMap.find(pText);
1535  assert(pos != this->mTextMap.end());
1536 
1537  if (pos->second != NULL && pos->second->mTextureName != 0)
1538  {
1539  //std::cout << "Drawing text \"" << pText->getText() << "\"." << std::endl;
1540  CLLayoutRenderer::draw_text(pos->second, x, y, z, pBB);
1541  }
1542 
1543  //restore the attributes
1545  }
1546 }
const C_FLOAT64 & getWidth() const
Definition: CLBase.h:211
const C_FLOAT64 & getDepth() const
Definition: CLBase.h:213
std::map< const CLText *, const CLTextTextureSpec * > mTextMap
const CLRelAbsVector & getZ() const
Definition: CLText.cpp:222
const CLRelAbsVector & getY() const
Definition: CLText.cpp:214
double getRelativeValue() const
void draw_text(const CLStyle *pStyle, const CLBoundingBox *pBB, const CLTextTextureSpec *pTexture)
CLGroupAttributes mCurrentAttributes
const CLDimensions & getDimensions() const
Definition: CLBase.h:266
static void extract_1d_attributes(const CLGraphicalPrimitive1D *pObject, CLGroupAttributes *attributes)
bool isSetText() const
Definition: CLText.cpp:374
double getAbsoluteValue() const
const C_FLOAT64 & getHeight() const
Definition: CLBase.h:212
static void extract_text_attributes(const T *pObject, CLGroupAttributes *attributes)
const CLRelAbsVector & getX() const
Definition: CLText.cpp:206
void CLLayoutRenderer::draw_text ( const CLTextTextureSpec pTexture,
double  x,
double  y,
double  z,
const CLBoundingBox pBB 
)
protected

Method to draw a string at the given position within the given bounding box.

pTexture->mScale

pTexture->mScale

Definition at line 1551 of file CLLayoutRenderer.cpp.

References CLText::ANCHOR_BOTTOM, CLText::ANCHOR_END, CLText::ANCHOR_MIDDLE, createGLMatrix(), CLBoundingBox::getPosition(), CLPoint::getX(), CLPoint::getY(), CLPoint::getZ(), mColorMap, mCurrentAttributes, CLGroupAttributes::mpTransform, CLTextTextureSpec::mScale, CLGroupAttributes::mStroke, CLGroupAttributes::mTextAnchor, CLTextureSpec::mTextHeight, CLTextureSpec::mTextureHeight, CLTextureSpec::mTextureName, CLTextureSpec::mTextureWidth, CLTextureSpec::mTextWidth, CLGroupAttributes::mVTextAnchor, CLGroupAttributes::mX, and mZoomFactor.

1552 {
1553  //std::cout << "Drawing text with texture at " << pTexture << std::endl;
1554  if (pTexture != NULL && pBB != NULL)
1555  {
1556  // create a texture for the text.
1557  // map the origin of the texture to x,y,z
1558  // map the texture point at textwidth, textheight to x+textwidth,
1559  // y+textheight
1560  // This might lead to text that goes beyone the dimensions of the bounding
1561  // box, but since the user has asked for a text of this size, we just draw
1562  // it
1563  std::map<std::string, CLRGBAColor>::const_iterator pos = this->mColorMap.find(mCurrentAttributes.mStroke);
1564  assert(pos != this->mColorMap.end());
1565  const CLRGBAColor& c = pos->second;
1566  glColor4ub(c.mR, c.mG, c.mB, c.mA);
1567  double xOffset = x + pBB->getPosition().getX();
1568  double yOffset = y + pBB->getPosition().getY();
1569  double zOffset = z + pBB->getPosition().getZ();
1570 
1571  // position the text according to how the anchor is set
1573  {
1574  // the new interpretation is that the horizontal center of the text is at xOffset,yOffset
1575  xOffset -= pTexture->mTextWidth / (2.0 * this->mZoomFactor);
1576  }
1578  {
1579  // the new interpretation is that xOffset specifies the horizontal end of the text, so
1580  // the start has to be placed at xOffset-pTexture->mTextWidth / this->mZoomFactor
1581  xOffset -= pTexture->mTextWidth / this->mZoomFactor;
1582  }
1583 
1584  // do vertical positioning
1586  {
1587  // the text is vertically centered in the box
1588  yOffset -= pTexture->mTextHeight / (2.0 * this->mZoomFactor);
1589  }
1591  {
1592  // the lower edge of the text is located at the top edge of the box
1593  // since heigher y values are downward, this alligns the text at
1594  // the lower end of the box
1595  yOffset -= pTexture->mTextHeight / this->mZoomFactor;
1596  }
1597 
1598  // the yOffset has to consider the mAscent of the text because the
1599  // placement of the text should be relative to the baseline
1600  //std::cout << "current bounding box position: " << pBB->getPosition().getX() << "," << pBB->getPosition().getY() << std::endl;
1601  //std::cout << "texture size: " << pTexture->textureWidth << "x" << pTexture->textureHeight << std::endl;
1602  //std::cout << "text size: " << pTexture->textWidth << "x" << pTexture->textHeight << std::endl;
1603  //std::cout << "text mAscent: " << pTexture->mAscent << std::endl;
1604  //std::cout << "y offset at: " << y << std::endl;
1605  //std::cout << "placing baseline at: " << yOffset << std::endl;
1606  //std::cout << "the upper side of the textured box will be located at: " << yOffset << std::endl;
1607 
1608  //
1609  // we draw a rectangle in the current stroke color. At places where the texture is black, the underlying color should be seen.
1610  // load the texture
1611  // enable 2D texturing
1612  glEnable(GL_TEXTURE_2D);
1613  glBindTexture(GL_TEXTURE_2D, pTexture->mTextureName);
1614  glMatrixMode(GL_MODELVIEW);
1615  glPushMatrix();
1616  glTranslated(xOffset, yOffset, zOffset);
1617 
1618  // apply the current transformation
1619  if (memcmp(mCurrentAttributes.mpTransform, Transformation::getIdentityMatrix(), 12 * sizeof(double)))
1620  {
1621  // move back to the current offset
1622  glTranslated(this->mCurrentAttributes.mX, this->mCurrentAttributes.mY, this->mCurrentAttributes.mZ);
1623  GLdouble* matrix = new GLdouble[16];
1625  glMultMatrixd(matrix);
1626  delete[] matrix;
1627  // move to 0.0,0.0,0.0
1628  glTranslated(-this->mCurrentAttributes.mX, -this->mCurrentAttributes.mY, -this->mCurrentAttributes.mZ);
1629  }
1630 
1631  //std::cout << "zoom factor: " << this->mZoomFactor << std::endl;
1632  //std::cout << "Drawing texture " << pTexture->mTextureName << " with:" << std::endl;
1633  //std::cout << "text height: " << pTexture->mTextHeight << " text width: " << pTexture->mTextWidth << std::endl;
1634  //std::cout << "texture height: " << pTexture->mTextureHeight << " texture width: " << pTexture->mTextureWidth << std::endl;
1635  //std::cout << "texture scale: " << pTexture->mScale << std::endl;
1636  double widthRatio = pTexture->mTextWidth /** pTexture->mScale*/ / pTexture->mTextureWidth;
1637  //std::cout << "width ratio: " << widthRatio << std::endl;
1638  double heightRatio = pTexture->mTextHeight /** pTexture->mScale*/ / pTexture->mTextureHeight;
1639  //std::cout << "height ratio: " << heightRatio << std::endl;
1640  glBegin(GL_POLYGON);
1641  glTexCoord2f(0.0, 1.0);
1642  glVertex3f(0.0, 0.0, 0.0);
1643  glTexCoord2d(0.0, 1.0 - heightRatio);
1644  glVertex3d(0.0, pTexture->mTextHeight / pTexture->mScale, 0.0);
1645  glTexCoord2d(widthRatio, 1.0 - heightRatio);
1646  glVertex3d(pTexture->mTextWidth / pTexture->mScale, pTexture->mTextHeight / pTexture->mScale, 0.0);
1647  glTexCoord2d(widthRatio, 1.0);
1648  glVertex3d(pTexture->mTextWidth / pTexture->mScale, 0.0, 0.0);
1649  glEnd();
1650  glPopMatrix();
1651  // disable the 2D texture again
1652  glDisable(GL_TEXTURE_2D);
1653  }
1654 }
static void createGLMatrix(const double *const matrix, GLdouble *glMatrix)
const C_FLOAT64 & getZ() const
Definition: CLBase.h:85
CLText::TEXT_ANCHOR mTextAnchor
CLGroupAttributes mCurrentAttributes
const C_FLOAT64 & getX() const
Definition: CLBase.h:83
const CLPoint & getPosition() const
Definition: CLBase.h:265
std::map< std::string, CLRGBAColor > mColorMap
double mTextureWidth
const C_FLOAT64 & getY() const
Definition: CLBase.h:84