diff options
Diffstat (limited to 'src/pmview/link.cpp')
-rw-r--r-- | src/pmview/link.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/src/pmview/link.cpp b/src/pmview/link.cpp new file mode 100644 index 0000000..bddfb0c --- /dev/null +++ b/src/pmview/link.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 1997 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2009 Aconex. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <Inventor/nodes/SoSeparator.h> +#include <Inventor/nodes/SoTranslation.h> +#include <Inventor/nodes/SoRotationXYZ.h> +#include <Inventor/nodes/SoCylinder.h> +#include <Inventor/nodes/SoSphere.h> +#include <Inventor/nodes/SoBaseColor.h> + +#include "togglemod.h" +#include "link.h" +#include "defaultobj.h" + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ + * Constructor for the Link. + * Note that we use different alignment for the base than the one + * for the scene. Base is always centered and we get the visual + * effect by addjusting the height of the cylinder(s). + \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +Link::Link (const DefaultObj & defs, + int c, int r, + int colSpan, int rowSpan, + Alignment a) + : BaseObj (false, defs, c, r, colSpan, rowSpan, center) + , _tag ("\n") +{ + _objtype |= LINK; + + for ( int i=0; i < 3; i++) { + _color[i] = defs.baseColor(i); + } + + align = a; + c1 = c2 = 0; + cellHeight = defs.baseHeight(); + cellDepth = defs.baseHeight(); + cellWidth = defs.baseHeight(); + + _width = colSpan * cellWidth; + _depth = rowSpan * cellDepth; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ + * +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +void +Link::finishedAdd () +{ + BaseObj::addBase (_root); + + SoBaseColor * color = new SoBaseColor; + color->rgb.setValue (_color); + _root->addChild (color); + + float radius = cellHeight * 0.4; + + SoSeparator * mainsep = new SoSeparator; + + SoTranslation * toCenter = new SoTranslation; + toCenter->translation.setValue (_width/2.0, cellHeight/2.0, _depth/2.0); + mainsep->addChild (toCenter); + + if ( align == northEast || align == northWest || + align == southEast || align == southWest ) { + SoRotationXYZ * mrot = new SoRotationXYZ; + mrot->axis = SoRotationXYZ::Y; + switch (align) { + case northEast: + mrot->angle = 0; + break; + + case northWest: + mrot->angle = M_PI/2; + break; + + case southWest: + mrot->angle = M_PI; + break; + + case southEast: + mrot->angle = -(M_PI/2); + break; + + default: + break; + } + mainsep->addChild (mrot); + + + // L-shape link - could leave without a separator, but + // geometry calculation becomes messy, so just add one. + SoSeparator * sp = new SoSeparator; + + SoSphere * s = new SoSphere; + s->radius.setValue (radius); + sp->addChild (s); + + t2 = new SoTranslation; + t3 = new SoTranslation; + + c1 = new SoCylinder; + c1->radius.setValue (radius); + + c2 = new SoCylinder; + c2->radius.setValue (radius); + + if ( align == northEast || align == southWest ) { + c1->height.setValue (_depth/2.0); + c2->height.setValue (_width/2.0); + + t2->translation.setValue (0, 0, _depth/-4.0); + t3->translation.setValue (_width/4.0, _depth/4.0, 0); + } else { + c1->height.setValue (_width/2.0); + c2->height.setValue (_depth/2.0); + + t2->translation.setValue (0, 0, _width/-4.0); + t3->translation.setValue (_depth/4.0, _width/4.0, 0); + } + + sp->addChild (t2); + + SoRotationXYZ * r1 = new SoRotationXYZ; + r1->axis = SoRotationXYZ::X; + r1->angle = M_PI/2; + + sp->addChild (r1); + sp->addChild (c1); + sp->addChild (t3); + + SoRotationXYZ * r2 = new SoRotationXYZ; + r2->axis = SoRotationXYZ::Z; + r2->angle = M_PI/2; + + sp->addChild (r2); + sp->addChild (c2); + + mainsep->addChild (sp); + } else { + SoRotationXYZ * r = new SoRotationXYZ; + + int h; + + if ( align == north || align == south ) { // Vertical pipe + h = rows() * cellDepth; + + r->axis = SoRotationXYZ::X; + r->angle = M_PI/2; + } else { // Horizontal pipe + h = cols() * cellWidth; + + r->axis = SoRotationXYZ::Z; + r->angle = M_PI/2; + } + + mainsep->addChild (r); + + c1 = new SoCylinder; + c1->radius.setValue (radius); + c1->height.setValue (h); + mainsep->addChild (c1); + } + + + ToggleMod * m = new ToggleMod (mainsep, (const char *)_tag.toAscii()); + _root->addChild (m->root()); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ + * Adjust the size of the link. Note, that we don't need to change the + * reported width and depth of an object (Grid does not cope with such + * changes very well) just adjust the length of cylinder(s). +\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +void +Link::setTran (float x, float z, int w, int d) +{ + if ( c1 && c2 ) { + if ( align == northEast || align == southWest ) { + c1->height.setValue (d/2.0); + c2->height.setValue (w/2.0); + + t2->translation.setValue (0, 0, d/-4.0); + t3->translation.setValue (w/4.0, d/4.0, 0); + } else { + c1->height.setValue (w/2.0); + c2->height.setValue (d/2.0); + + t2->translation.setValue (0, 0, w/-4.0); + t3->translation.setValue (d/4.0, w/4.0, 0); + } + } else { + c1->height.setValue ((align == north || align == south ) ? d : w ); + } + + BaseObj::setTran (x, z, w, d); +} + +void +Link::setTag (const char * s) +{ + _tag = s; + + if ( strchr (s, '\n') == NULL ) { + _tag.append ("\n"); + } +} |