/* * 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 #include #include #include #include #include #include #include "stackmod.h" #include "togglemod.h" #include "pipeobj.h" #include "defaultobj.h" #include "colorlist.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * Constructor for Pipe. * Note that similar to Link, pipes are always centered * relative to the grid. The aligment is used to decide * which end of pipe is decorated and in what direction * pipe is oriented. \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ PipeObj::PipeObj (const DefaultObj & defs, int c, int r, int colSpan, int rowSpan, BaseObj::Alignment align) : ModObj (false, defs, c, r, colSpan, rowSpan, center) , _align(align) , _tag ("\n") { _objtype |= PIPEOBJ; for ( int i=0; i < 3; i++) { _color[i] = defs.baseColor(i); } _cylTrans = 0; _origt = 0; _cyl = 0; _stackHeight = defs.pipeLength(); cellHeight = defs.baseHeight(); if ( _align == north || _align == south ) { cellWidth = defs.baseHeight(); cellDepth = (defs.pipeLength() < cellHeight) ? cellHeight : defs.pipeLength(); } else { cellWidth = (defs.pipeLength() < cellHeight) ? cellHeight : defs.pipeLength(); cellDepth = defs.baseHeight(); } _width = colSpan * cellWidth; _depth = rowSpan * cellDepth; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void PipeObj::finishedAdd () { BaseObj::addBase (_root); int h; SoSeparator * sp = new SoSeparator; _root->addChild (sp); SoTranslation * st = new SoTranslation; st->translation.setValue (_width/2.0, cellHeight/2.0, _depth/2.0); sp->addChild (st); SoRotationXYZ * r = new SoRotationXYZ; if ( _align == north || _align == south ) { // Vertical Pipe h = _depth; r->axis = SoRotationXYZ::X; r->angle = M_PI/((_align == north) ? 2 : -2); } else { // Horizontal pipe h = _width; r->axis = SoRotationXYZ::Z; r->angle = M_PI/((_align == east) ? 2 : -2); } sp->addChild (r); SoSeparator * sceneSp = new SoSeparator; sp->addChild (sceneSp); _origt = new SoTranslation; _origt->translation.setValue (0, -h/2.0, 0); sceneSp->addChild (_origt); if (_metrics.numMetrics() ) { SoSeparator * stacksp = new SoSeparator; const ColorSpec * colSpec; SoScale *scale = new SoScale(); scale->scaleFactor.setValue(cellHeight*0.8, _stackHeight, cellHeight*0.8); stacksp->addChild(scale); if ((colSpec = theColorLists.list((const char *)_colors.toAscii()))) { if (colSpec->_scale) pmprintf( "%s: Warning: Color scale cannot be applied to pipe\n", pmProgname); else { for (int i = 0; i < colSpec->_list.size(); i++) _metrics.add(*(colSpec->_list)[i]); } } else { pmprintf("%s: Warning: No colours specified for pipe" "defaulting to blue.\n", pmProgname); } _metrics.resolveColors(MetricList::perValue); StackMod * _stack = new StackMod(&_metrics, ViewObj::object (cylinder), StackMod::fixed); _stack->setFillColor(_color); _stack->setFillText((const char *)_tag.toAscii()); stacksp->addChild(_stack->root()); sceneSp->addChild(stacksp); BaseObj::add(_stack); ViewObj::theNumModObjects++; } else { pmprintf("%s: Error: no metrics for pipe\n", pmProgname); } SoBaseColor * color = new SoBaseColor; color->rgb.setValue (_color); sceneSp->addChild (color); _cylTrans = new SoTranslation; _cylTrans->translation.setValue (0, (h+_stackHeight)/2.0, 0); sceneSp->addChild (_cylTrans); _cyl = new SoCylinder; _cyl->radius.setValue (cellHeight*0.4); _cyl->height.setValue (h - _stackHeight); // In theory, something like "StaticMod", i.e no metrics, no // nothing should be provided, but togglemod seems to be // working Ok, so.... ToggleMod * m = new ToggleMod (_cyl, (const char *)_tag.toAscii()); sceneSp->addChild (m->root()); } void PipeObj::setTran (float x, float z, int w, int d) { if ( _cyl ) { float h = (_align == north || _align == south) ? d : w; _cylTrans->translation.setValue (0, (h + _stackHeight)/2.0, 0); _origt->translation.setValue (0, -h/2.0, 0); _cyl->height.setValue (h - _stackHeight); } ModObj::setTran (x, z, w, d); } void PipeObj::setTag (const char * s) { _tag = s; if ( strchr (s, '\n' ) == NULL ) { _tag.append ("\n"); } }