Add ClusterShadingStage
[opensg.git] / Source / System / GraphOp / OSGDotFileGeneratorGraphOp.cpp
blob0ccf4cb024d9743aa8c504223bc709a880b5142e
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2008 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
18 * *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 #include <sstream>
40 #include <boost/foreach.hpp>
42 #include "OSGDotFileGeneratorGraphOp.h"
43 #include "OSGContainerCollection.h"
44 #include "OSGGraphOpFactory.h"
45 #include "OSGGroup.h"
46 #include "OSGMaterialGroup.h"
47 #include "OSGMaterialChunkOverrideGroup.h"
48 #include "OSGNameAttachment.h"
49 #include "OSGDistanceLOD.h"
50 #include "OSGScreenLOD.h"
51 #include "OSGLight.h"
52 #include "OSGSwitch.h"
53 #include "OSGMultiCore.h"
54 #include "OSGVisitSubTree.h"
55 #include "OSGTransform.h"
56 #include "OSGTextureObjChunk.h"
57 #include "OSGClipPlaneChunk.h"
58 #include "OSGLightChunk.h"
59 #include "OSGChunkMaterial.h"
60 #include "OSGSwitchMaterial.h"
61 #include "OSGMultiPassMaterial.h"
62 #include "OSGGeometry.h"
64 /*! \class OSG::DotFileGeneratorGraphOp
65 \ingroup GrpContribDataSolidGraphOp
67 Writes a Graphviz dot file representation of the graph.
70 OSG_BEGIN_NAMESPACE
72 namespace
74 static bool registerOp(void)
76 GraphOpRefPtr newOp = DotFileGeneratorGraphOp::create();
78 GraphOpFactory::the()->registerOp(newOp);
79 return true;
82 static OSG::StaticInitFuncWrapper registerOpWrapper(registerOp);
83 } // namespace
86 DotFileGeneratorGraphOp::Info::Info(void) :
87 cnt ( 0),
88 label ( ),
89 name ( ),
90 id ( ),
91 fontcolor( ),
92 obj_id (NULL ),
93 finished (false)
97 DotFileGeneratorGraphOp::Info::Info(const Info &other) :
98 cnt (other.cnt ),
99 label (other.label ),
100 name (other.name ),
101 id (other.id ),
102 fontcolor(other.fontcolor),
103 obj_id (other.obj_id ),
104 finished (other.finished )
108 DotFileGeneratorGraphOp::Info::~Info(void)
112 DotFileGeneratorGraphOp::Info&
113 DotFileGeneratorGraphOp::Info::operator=(const Info& rhs)
115 cnt = rhs.cnt;
116 label = rhs.label;
117 name = rhs.name;
118 id = rhs.id;
119 fontcolor = rhs.fontcolor;
120 obj_id = rhs.obj_id;
121 finished = rhs.finished;
123 return *this;
126 DotFileGeneratorGraphOp::BrewerColor::BrewerColor(const std::string &schemeIn,
127 const std::string &numberIn) :
128 scheme(schemeIn),
129 number(numberIn)
133 DotFileGeneratorGraphOp::BrewerColor::~BrewerColor(void)
137 const DotFileGeneratorGraphOp::BrewerColor &
138 DotFileGeneratorGraphOp::Colors::color(void) const
140 if (_current >= _colors.size())
141 _current = 0;
143 if (_current >= _colors.size())
144 throw std::out_of_range("no color available");
146 return _colors[_current++];
149 void DotFileGeneratorGraphOp::Colors::add(const std::string &scheme,
150 UInt32 start,
151 UInt32 end )
153 for (UInt32 i = start; i <= end; ++i)
155 std::stringstream number;
156 number << i;
157 _colors.push_back(BrewerColor(scheme, number.str()));
161 DotFileGeneratorGraphOp::Colors::Colors(void) :
162 _colors ( ),
163 _current(0)
167 DotFileGeneratorGraphOp::Colors::~Colors(void)
171 const char *DotFileGeneratorGraphOp::getClassname(void)
173 return "DotFileGeneratorGraphOp";
176 DotFileGeneratorGraphOp::DotFileGeneratorGraphOp(const char* name) :
177 Inherited(name),
178 _filename("out.dot"),
179 _include_attachment(true),
180 _no_name_attachments(true),
181 _no_ranks(false),
182 _max_node_children(-1),
183 _size(""),
184 _ranksep("2.5"),
185 _nodesep("1.0"),
186 _graph_attributes(""),
187 _spStream(),
188 _mapInfo(),
189 _node_cnt(0),
190 _core_cnt(0),
191 _attachment_cnt(0),
192 _material_cnt(0),
193 _matrix_cnt(0),
194 _image_cnt(0),
195 _chunk_cnt(0),
196 _integral_prop_cnt(0),
197 _vector_prop_cnt(0),
198 _space(0),
199 _colors(),
200 _usedColors(),
201 _suppressed(),
202 _suppressed_derived(),
203 _dotted_edges(),
204 _edges()
206 // nothing to do
209 DotFileGeneratorGraphOpTransitPtr
210 DotFileGeneratorGraphOp::create(void)
212 return DotFileGeneratorGraphOpTransitPtr(new DotFileGeneratorGraphOp);
215 GraphOpTransitPtr DotFileGeneratorGraphOp::clone(void)
217 return GraphOpTransitPtr(new DotFileGeneratorGraphOp);
220 void DotFileGeneratorGraphOp::setParams(const std::string params)
222 ParamSet ps(params);
224 ps("filename", _filename);
225 ps("include_attachment", _include_attachment);
226 ps("no_name_attachments", _no_name_attachments);
227 ps("no_ranks", _no_ranks);
228 ps("max_node_children", _max_node_children);
229 ps("size", _size);
230 ps("ranksep", _ranksep);
231 ps("nodesep", _nodesep);
232 ps("graph_attributes", _graph_attributes);
234 std::string out = ps.getUnusedParams();
235 if(out.length())
237 FWARNING(("DotFileGeneratorGraphOp doesn't have parameters '%s'\n.",
238 out.c_str()));
242 std::string DotFileGeneratorGraphOp::usage(void)
244 return
245 "DotFileGenerator: Writes Graphiz dot file of graph\n"
246 "Params: name (type, default)\n"
247 " filename (std::string, \"out.dot\"): output file name\n"
248 " include_attachment (bool, true): include attachments in graph\n"
249 " no_name_attachments (bool, true): include attachments in graph\n"
250 " no_ranks (bool, true): do not use rank statement in graph\n"
251 " max_node_children (Int32, -1): maximum number of children added to graph\n"
252 " size (std::string, \"\"): size attribute of graph\n"
253 " ranksep (std::string, \"1.5\"): ranksep attribute of graph\n"
254 " nodesep (std::string, \"1.0\"): nodesep attribute of graph\n"
255 " graph_attributes (std::string, \"\"): arbitrary graph attribute entry\n";
258 void DotFileGeneratorGraphOp::insert(const TypeBase* t, bool derived_from)
260 if(derived_from)
262 _suppressed_derived.push_back(t);
264 else
266 _suppressed.push_back(t);
270 bool DotFileGeneratorGraphOp::isSuppressed(const TypeBase& t)
272 VecTypesT::const_iterator iter, end;
274 iter = _suppressed.begin();
275 end = _suppressed.end();
277 for(; iter != end; ++iter)
279 if ((*iter)->getId() == t.getId())
280 return true;
283 iter = _suppressed_derived.begin();
284 end = _suppressed_derived.end();
286 for (; iter != end; ++iter)
288 const TypeBase& other = *(*iter);
290 if (t.isDerivedFrom(other))
291 return true;
294 return false;
297 DotFileGeneratorGraphOp::~DotFileGeneratorGraphOp(void)
299 deinitialize();
302 Action::ResultE DotFileGeneratorGraphOp::traverseEnter(Node * const node)
304 if(isInExcludeList(node))
305 return Action::Skip;
307 Node* parent = node->getParent();
308 NodeCore* core = node->getCore();
310 if(_max_node_children > 0 &&
311 parent &&
312 _node_cnt > 0 &&
313 parent->findChild(node) >= Int32(_max_node_children))
315 Info& parent_info = NodeInfo(parent);
317 if(!parent_info.finished)
319 parent_info.finished = true;
321 Info node_info =
322 EtceteraInfo(parent->getNChildren() - _max_node_children);
324 DefineEtceteraNode(node_info);
325 DefineNodeEdge(parent_info, node_info);
328 return Action::Skip;
331 const Info &node_info = NodeInfo(node);
332 const Info &core_info = CoreInfo(core);
334 bool suppressed = isSuppressed(core->getType());
336 if (!suppressed)
337 OpenGroup(true);
339 DefineNode(node_info);
341 if(!suppressed)
343 DefineCore(core_info);
344 DefineCoreEdge(node_info, core_info);
347 if(!suppressed)
349 CloseGroup();
351 HandleMaterial (core, core_info);
352 HandleLight (core, core_info);
353 HandleVisitSubTree(core, core_info);
354 HandleTransform (core, core_info);
355 HandleGeometry (core, core_info);
356 HandleAttachment (core, core_info);
359 HandleAttachment(node, node_info);
361 if(parent)
363 DefineNodeEdge(NodeInfo(parent), node_info);
366 return Action::Continue;
369 void DotFileGeneratorGraphOp::HandleMaterial( NodeCore * const core,
370 const Info & info)
372 Material *mat = NULL;
373 MaterialGroup *mgrp = dynamic_cast<MaterialGroup*>(core);
375 if(mgrp)
377 mat = mgrp->getMaterial();
379 else
381 MaterialChunkOverrideGroup *mcogrp =
382 dynamic_cast<MaterialChunkOverrideGroup*>(core);
384 if(mcogrp)
386 mat = mcogrp->getMaterial();
388 else
390 Geometry *geom = dynamic_cast<Geometry*>(core);
392 if(geom)
394 mat = geom->getMaterial();
399 if(mat)
401 bool suppressed = isSuppressed(mat->getType());
403 if(suppressed)
404 return;
406 OpenGroup(true);
408 const Info &mat_info = MaterialInfo(mat);
410 DefineMaterial(mat_info);
411 DefineSimpleEdge(info, mat_info);
413 CloseGroup();
415 HandleChunkMaterial (mat, mat_info);
416 HandleSwitchMaterial (mat, mat_info);
417 HandleMultiPassMaterial(mat, mat_info);
421 void DotFileGeneratorGraphOp::HandleTransform( NodeCore * const core,
422 const Info & info)
424 Transform *trafo = dynamic_cast<Transform*>(core);
426 if(trafo)
428 void *handler = &const_cast<Matrix&>(trafo->getMatrix());
430 if(!hasInfo(handler))
432 OpenGroup(true);
434 Info mat_info = MatrixInfo(trafo->getMatrix(), handler);
436 DefineMatrix(mat_info);
437 DefineSimpleEdge(info, mat_info);
439 CloseGroup();
444 void DotFileGeneratorGraphOp::HandleGeometry( NodeCore * const core,
445 const Info & info)
447 Geometry *geom = dynamic_cast<Geometry*>(core);
449 if(geom)
451 OpenGroup(false);
453 GeoIntegralProperty *types = geom->getTypes();
454 GeoIntegralProperty *length = geom->getLengths();
455 GeoVectorProperty *vertices = geom->getPositions();
456 GeoVectorProperty *normales = geom->getNormals();
457 GeoVectorProperty *colors = geom->getColors();
458 GeoVectorProperty *sec_colors = geom->getSecondaryColors();
459 GeoVectorProperty *tex_coords = geom->getTexCoords();
460 GeoVectorProperty *tex1_coords = geom->getTexCoords1();
461 GeoVectorProperty *tex2_coords = geom->getTexCoords2();
462 GeoVectorProperty *tex3_coords = geom->getTexCoords3();
463 GeoVectorProperty *tex4_coords = geom->getTexCoords4();
464 GeoVectorProperty *tex5_coords = geom->getTexCoords5();
465 GeoVectorProperty *tex6_coords = geom->getTexCoords6();
466 GeoVectorProperty *tex7_coords = geom->getTexCoords7();
468 if(types && types->size() > 0)
470 Info prop_info = IntegralPropInfo(types, "types");
471 DefineProperty(prop_info);
472 DefineSimpleEdge(info, prop_info);
475 if(length && length->size() > 0)
477 Info prop_info = IntegralPropInfo(length, "length");
478 DefineProperty(prop_info);
479 DefineSimpleEdge(info, prop_info);
482 if(vertices && vertices->size() > 0)
484 Info prop_info = VectorPropInfo(vertices, "vertices");
485 DefineProperty(prop_info);
486 DefineSimpleEdge(info, prop_info);
489 if(normales && normales->size() > 0)
491 Info prop_info = VectorPropInfo(normales, "normales");
492 DefineProperty(prop_info);
493 DefineSimpleEdge(info, prop_info);
496 if(colors && colors->size() > 0)
498 Info prop_info = VectorPropInfo(colors, "colors");
499 DefineProperty(prop_info);
500 DefineSimpleEdge(info, prop_info);
503 if(sec_colors && sec_colors->size() > 0)
505 Info prop_info = VectorPropInfo(sec_colors, "sec_colors");
506 DefineProperty(prop_info);
507 DefineSimpleEdge(info, prop_info);
510 if(tex_coords && tex_coords->size() > 0)
512 Info prop_info = VectorPropInfo(tex_coords, "tex_coords");
513 DefineProperty(prop_info);
514 DefineSimpleEdge(info, prop_info);
517 if(tex1_coords && tex1_coords->size() > 0)
519 Info prop_info = VectorPropInfo(tex1_coords, "tex1_coords");
520 DefineProperty(prop_info);
521 DefineSimpleEdge(info, prop_info);
524 if(tex2_coords && tex2_coords->size() > 0)
526 Info prop_info = VectorPropInfo(tex2_coords, "tex2_coords");
527 DefineProperty(prop_info);
528 DefineSimpleEdge(info, prop_info);
531 if(tex3_coords && tex3_coords->size() > 0)
533 Info prop_info = VectorPropInfo(tex3_coords, "tex3_coords");
534 DefineProperty(prop_info);
535 DefineSimpleEdge(info, prop_info);
538 if(tex4_coords && tex4_coords->size() > 0)
540 Info prop_info = VectorPropInfo(tex4_coords, "tex4_coords");
541 DefineProperty(prop_info);
542 DefineSimpleEdge(info, prop_info);
545 if(tex5_coords && tex5_coords->size() > 0)
547 Info prop_info = VectorPropInfo(tex5_coords, "tex5_coords");
548 DefineProperty(prop_info);
549 DefineSimpleEdge(info, prop_info);
552 if(tex6_coords && tex6_coords->size() > 0)
554 Info prop_info = VectorPropInfo(tex6_coords, "tex6_coords");
555 DefineProperty(prop_info);
556 DefineSimpleEdge(info, prop_info);
559 if(tex7_coords && tex7_coords->size() > 0)
561 Info prop_info = VectorPropInfo(tex7_coords, "tex7_coords");
562 DefineProperty(prop_info);
563 DefineSimpleEdge(info, prop_info);
566 CloseGroup();
570 void DotFileGeneratorGraphOp::HandleTextureChunk(
571 StateChunk * const chunk,
572 const Info & info)
574 TextureObjChunk *textureobjchunk = dynamic_cast<TextureObjChunk*>(chunk);
576 if(textureobjchunk)
578 Image *image = textureobjchunk->getImage();
580 if(image)
582 bool suppressed = isSuppressed(image->getType());
584 if(suppressed)
585 return;
587 OpenGroup(true);
589 const Info &image_info = ImageInfo(image);
591 DefineMatrix(image_info);
592 DefineSimpleEdge(info, image_info);
594 CloseGroup();
599 void DotFileGeneratorGraphOp::HandleLight( NodeCore * const core,
600 const Info & info)
602 Light *light = dynamic_cast<Light*>(core);
604 if(light)
606 Node *beacon = light->getBeacon();
608 if(beacon)
610 const Info& light_info = CoreInfo(light);
611 const Info& beacon_info = NodeInfo(beacon);
613 _dotted_edges.push_back(std::make_pair(light_info, beacon_info));
618 void DotFileGeneratorGraphOp::HandleVisitSubTree( NodeCore * const core,
619 const Info & info)
621 VisitSubTree *visitSubTree = dynamic_cast<VisitSubTree*>(core);
623 if(visitSubTree)
625 Node *subTreeRoot = visitSubTree->getSubTreeRoot();
627 if(subTreeRoot)
629 OpenGroup(true);
631 const Info& visit_sub_tree_info = CoreInfo(visitSubTree);
632 const Info& sub_tree_root_info = NodeInfo(subTreeRoot);
634 DefineSimpleEdge(visit_sub_tree_info, sub_tree_root_info);
636 CloseGroup();
638 traverse(subTreeRoot);
644 void DotFileGeneratorGraphOp::HandleBeaconedChunk(
645 StateChunk * const chunk,
646 const Info & info )
648 ClipPlaneChunk *clippl = dynamic_cast<ClipPlaneChunk*>(chunk);
650 if(clippl)
652 Node *beacon = clippl->getBeacon();
654 if(beacon)
656 const Info& clippl_info = StateChunkInfo(clippl);
657 const Info& beacon_info = NodeInfo(beacon);
659 _dotted_edges.push_back(std::make_pair(clippl_info, beacon_info));
663 LightChunk *light = dynamic_cast<LightChunk*>(chunk);
665 if(light)
667 Node *beacon = light->getBeacon();
669 if(beacon)
671 const Info& light_info = StateChunkInfo(light);
672 const Info& beacon_info = NodeInfo(beacon);
674 _dotted_edges.push_back(std::make_pair(light_info, beacon_info));
679 void DotFileGeneratorGraphOp::HandleSwitchMaterial(
680 Material * const material,
681 const Info & info )
683 SwitchMaterial *switchMat = dynamic_cast<SwitchMaterial*>(material);
685 if(switchMat)
687 UInt32 num = switchMat->editMFMaterials()->size();
689 for(UInt32 i = 0; i < num; ++i)
691 Material *mat = switchMat->getMaterial(i);
693 if(mat)
695 bool suppressed = isSuppressed(mat->getType());
697 if(suppressed)
698 continue;
700 OpenGroup(true);
702 std::stringstream label;
703 label << "label=" << i;
705 const Info &mat_info = MaterialInfo(mat);
707 DefineMaterial(mat_info);
708 DefineSimpleEdge(info, mat_info, true, label.str());
710 CloseGroup();
712 HandleChunkMaterial (mat, mat_info);
713 HandleSwitchMaterial (mat, mat_info);
714 HandleMultiPassMaterial(mat, mat_info);
720 void DotFileGeneratorGraphOp::HandleChunkMaterial(
721 Material * const material,
722 const Info & info )
724 ChunkMaterial *chunkMat = dynamic_cast<ChunkMaterial*>(material);
726 if(chunkMat)
728 OpenGroup(false);
730 const MFUnrecStateChunkPtr *chunks = chunkMat->getMFChunks();
732 MFUnrecStateChunkPtr::const_iterator iter = chunks->begin();
733 MFUnrecStateChunkPtr::const_iterator end = chunks->end();
735 for(; iter != end; ++iter)
737 StateChunkUnrecPtr statechunk = *iter;
739 if(!statechunk)
740 continue;
742 bool suppressed = isSuppressed(statechunk->getType());
744 if(suppressed)
745 continue;
747 const Info &chunk_info = StateChunkInfo(statechunk);
749 DefineStateChunk(chunk_info);
750 DefineSimpleEdge(info, chunk_info);
752 HandleTextureChunk(statechunk, chunk_info);
753 HandleBeaconedChunk(statechunk, chunk_info);
756 CloseGroup();
760 void DotFileGeneratorGraphOp::HandleMultiPassMaterial(
761 Material * const material,
762 const Info & info )
764 MultiPassMaterial *multiPassMat =
765 dynamic_cast<MultiPassMaterial*>(material);
767 if(multiPassMat)
769 UInt32 num = multiPassMat->editMFMaterials()->size();
771 for(UInt32 i = 0; i < num; ++i)
773 Material *mat = multiPassMat->getMaterials(i);
775 if(mat)
777 bool suppressed = isSuppressed(mat->getType());
779 if(suppressed)
780 continue;
782 OpenGroup(true);
784 std::stringstream label;
785 label << "label=" << i;
787 const Info &mat_info = MaterialInfo(mat);
789 DefineMaterial(mat_info);
790 DefineSimpleEdge(info, mat_info, true, label.str());
792 CloseGroup();
794 HandleChunkMaterial(mat, mat_info);
795 HandleSwitchMaterial(mat, mat_info);
796 HandleMultiPassMaterial(mat, mat_info);
803 void DotFileGeneratorGraphOp::HandleAttachment(
804 AttachmentContainer * const fc,
805 const Info & info)
807 if(_include_attachment)
809 if(!fc->getSFAttachments()->getValue().empty())
811 const SFAttachmentPtrMap* pAttMap = fc->getSFAttachments();
813 AttachmentMap::const_iterator mapIt;
814 AttachmentMap::const_iterator mapEnd;
816 bool flag = false;
818 mapIt = pAttMap->getValue().begin();
819 mapEnd = pAttMap->getValue().end();
821 for(; mapIt != mapEnd; ++mapIt)
823 AttachmentUnrecPtr att = mapIt->second;
825 if(att != NULL)
827 if (_no_name_attachments &&
828 Name::getClassType().getGroupId() == att->getGroupId())
830 continue;
833 if(ContainerCollection::getClassType().getGroupId() ==
834 att->getGroupId() )
836 ContainerCollectionUnrecPtr cc =
837 dynamic_pointer_cast<ContainerCollection>(att);
838 OSG_ASSERT(cc != NULL);
840 const MFUnrecFieldContainerPtr* field =
841 cc->getMFContainers();
842 MFUnrecFieldContainerPtr::const_iterator fIt =
843 field->begin();
844 MFUnrecFieldContainerPtr::const_iterator fEnd =
845 field->end ();
847 for(; fIt != fEnd; ++fIt)
849 // ToDo: Currently only Nodes are handled!
850 // Note: Endless loop might be possible?
851 Node* node = dynamic_cast<Node*>(*fIt);
852 if(node)
853 traverse(node);
857 flag = true;
861 if(!flag)
862 return;
864 OpenGroup(true);
866 mapIt = pAttMap->getValue().begin();
867 mapEnd = pAttMap->getValue().end();
869 for(; mapIt != mapEnd; ++mapIt)
871 AttachmentUnrecPtr att = mapIt->second;
872 if(att != NULL)
874 if(_no_name_attachments &&
875 Name::getClassType().getGroupId() == att->getGroupId())
877 continue;
880 const Info &attachment_info = AttachmentInfo(att);
882 DefineAttachment(attachment_info);
883 DefineAttachmentEdge(info, attachment_info);
885 if(ContainerCollection::getClassType().getGroupId() ==
886 att->getGroupId() )
888 ContainerCollectionUnrecPtr cc =
889 dynamic_pointer_cast<ContainerCollection>(att);
890 OSG_ASSERT(cc != NULL);
892 const MFUnrecFieldContainerPtr* field =
893 cc->getMFContainers();
894 MFUnrecFieldContainerPtr::const_iterator fIt =
895 field->begin();
896 MFUnrecFieldContainerPtr::const_iterator fEnd =
897 field->end ();
899 for(; fIt != fEnd; ++fIt)
901 // ToDo: Currently only Nodes are handled!
902 // Note: Endless loop might be possible?
903 Node* node = dynamic_cast<Node*>(*fIt);
904 if(node)
906 const Info& node_info = NodeInfo(node);
907 DefineHoldingEdge(attachment_info, node_info);
914 CloseGroup();
919 Action::ResultE DotFileGeneratorGraphOp::traverseLeave(
920 Node * const node,
921 Action::ResultE res )
923 return res;
926 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::NodeInfo(
927 Node * const node)
929 MapInfoT::iterator iter = _mapInfo.find(node);
931 if(iter != _mapInfo.end())
933 return iter->second;
935 else
937 _node_cnt++;
939 std::stringstream name, label;
941 name << "Node_" << _node_cnt;
942 label << "Node " << _node_cnt;
944 if(OSG::getName(node))
945 label << "\\n" << OSG::getName(node);
947 Info info;
949 info.cnt = _node_cnt;
950 info.name = name.str();
951 info.label = label.str();
952 info.id = node->getTypeName();
953 info.obj_id = node;
955 return _mapInfo.insert(
956 MapInfoT::value_type(node, info)).first->second;
960 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::CoreInfo(
961 NodeCore * const core)
963 MapInfoT::iterator iter = _mapInfo.find(core);
965 if(iter != _mapInfo.end())
967 return iter->second;
969 else
971 _core_cnt++;
973 std::string core_name = core->getTypeName();
975 std::stringstream name, label;
977 name << "Core_" << _core_cnt;
978 label << core_name << " " << _core_cnt;
980 if(OSG::getName(core))
981 label << "\\n" << OSG::getName(core);
983 Info info;
985 info.cnt = _core_cnt;
986 info.name = name.str();
987 info.label = label.str();
988 info.id = core_name;
989 info.obj_id = core;
991 Light *light = dynamic_cast<Light*>(core);
993 if(light && light->getOn())
994 info.fontcolor="0.000 1.000 1.000";
996 return _mapInfo.insert(
997 MapInfoT::value_type(core, info)).first->second;
1001 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::AttachmentInfo(
1002 Attachment * const att)
1004 MapInfoT::iterator iter = _mapInfo.find(att);
1006 if(iter != _mapInfo.end())
1008 return iter->second;
1010 else
1012 _attachment_cnt++;
1014 std::string attachment_name = att->getTypeName();
1016 std::stringstream name, label;
1018 name << "Attachment_" << _attachment_cnt;
1019 label << attachment_name << " " << _attachment_cnt;
1021 Name* attName = dynamic_cast<Name*>(att);
1022 if(attName)
1023 label << "\\n" << attName->getFieldPtr()->getValue().c_str();
1025 Info info;
1027 info.cnt = _attachment_cnt;
1028 info.name = name.str();
1029 info.label = label.str();
1030 info.id = attachment_name;
1031 info.obj_id = att;
1033 return _mapInfo.insert(
1034 MapInfoT::value_type(att, info)).first->second;
1038 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::MaterialInfo(
1039 Material * const material)
1041 MapInfoT::iterator iter = _mapInfo.find(material);
1043 if(iter != _mapInfo.end())
1045 return iter->second;
1047 else
1049 _material_cnt++;
1051 std::string material_name = material->getTypeName();
1053 std::stringstream name, label;
1055 name << "Material_" << _material_cnt;
1056 label << material_name << " " << _material_cnt;
1058 if(OSG::getName(material))
1059 label << "\\n" << OSG::getName(material);
1061 Info info;
1063 info.cnt = _material_cnt;
1064 info.name = name.str();
1065 info.label = label.str();
1066 info.id = material_name;
1067 info.obj_id = material;
1069 return _mapInfo.insert(
1070 MapInfoT::value_type(material, info)).first->second;
1074 DotFileGeneratorGraphOp::Info DotFileGeneratorGraphOp::MatrixInfo(
1075 const Matrix & matrix,
1076 void * handler)
1078 MapInfoT::iterator iter = _mapInfo.find(handler);
1080 if(iter != _mapInfo.end())
1082 return iter->second;
1084 else
1086 _matrix_cnt++;
1088 std::stringstream name, label;
1090 name << "Matrix_" << _matrix_cnt;
1091 label << "Matrix" << " " << _matrix_cnt;
1093 Info info;
1095 info.cnt = _matrix_cnt;
1096 info.name = name.str();
1097 info.label = label.str();
1098 info.id = "Matrix";
1099 info.obj_id = handler;
1101 return _mapInfo.insert(
1102 MapInfoT::value_type(handler, info)).first->second;
1106 DotFileGeneratorGraphOp::Info DotFileGeneratorGraphOp::EtceteraInfo(
1107 UInt32 number)
1109 std::stringstream name, label;
1111 name << "Etcetera";
1112 label << "Etcetera";
1113 label << "\\n" << "number = " << number;
1115 Info info;
1117 info.cnt = 0;
1118 info.name = name.str();
1119 info.label = label.str();
1120 info.id = "Etcetera";
1121 info.obj_id = 0;
1123 return info;
1126 DotFileGeneratorGraphOp::Info& DotFileGeneratorGraphOp::ImageInfo(
1127 Image * const image)
1129 MapInfoT::iterator iter = _mapInfo.find(image);
1131 if(iter != _mapInfo.end())
1133 return iter->second;
1135 else
1137 _image_cnt++;
1139 std::string image_name = image->getName();
1141 std::stringstream name, label;
1143 name << "Image_" << _image_cnt;
1144 label << "Image" << " " << _image_cnt;
1146 Info info;
1148 info.cnt = _image_cnt;
1149 info.name = name.str();
1150 info.label = label.str();
1151 info.id = "Image";
1152 info.obj_id = image;
1154 return _mapInfo.insert(
1155 MapInfoT::value_type(image, info)).first->second;
1159 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::StateChunkInfo(
1160 StateChunk * const chunk)
1162 MapInfoT::iterator iter = _mapInfo.find(chunk);
1164 if(iter != _mapInfo.end())
1166 return iter->second;
1168 else
1170 _chunk_cnt++;
1172 std::string chunk_name = chunk->getTypeName();
1174 std::stringstream name, label;
1176 name << "StateChunk_" << _chunk_cnt;
1177 label << chunk_name << " " << _chunk_cnt;
1179 if(OSG::getName(chunk))
1180 label << "\\n" << OSG::getName(chunk);
1182 Info info;
1184 info.cnt = _chunk_cnt;
1185 info.name = name.str();
1186 info.label = label.str();
1187 info.id = chunk_name;
1188 info.obj_id = chunk;
1190 return _mapInfo.insert(
1191 MapInfoT::value_type(chunk, info)).first->second;
1195 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::IntegralPropInfo(
1196 GeoIntegralProperty * const property,
1197 const char * context )
1199 MapInfoT::iterator iter = _mapInfo.find(property);
1201 if(iter != _mapInfo.end())
1203 return iter->second;
1205 else
1207 _integral_prop_cnt++;
1209 std::string property_name = property->getTypeName();
1211 std::stringstream name, label;
1213 name << "GeoIntegralProperty_" << _integral_prop_cnt;
1214 label << context;
1215 label << "\\n" << property_name << " " << _integral_prop_cnt;
1216 label << "\\n" << "size = " << property->size();
1218 Info info;
1220 info.cnt = _integral_prop_cnt;
1221 info.name = name.str();
1222 info.label = label.str();
1223 info.id = property_name+context;
1224 info.obj_id = property;
1226 return _mapInfo.insert(
1227 MapInfoT::value_type(property, info)).first->second;
1231 DotFileGeneratorGraphOp::Info &DotFileGeneratorGraphOp::VectorPropInfo(
1232 GeoVectorProperty * const property,
1233 const char * context )
1235 MapInfoT::iterator iter = _mapInfo.find(property);
1237 if(iter != _mapInfo.end())
1239 return iter->second;
1241 else
1243 _vector_prop_cnt++;
1245 std::string property_name = property->getTypeName();
1247 std::stringstream name, label;
1249 name << "GeoVectorProperty_" << _vector_prop_cnt;
1250 label << context;
1251 label << "\\n" << property_name << " " << _vector_prop_cnt;
1252 label << "\\n" << "size = " << property->size();
1254 Info info;
1256 info.cnt = _vector_prop_cnt;
1257 info.name = name.str();
1258 info.label = label.str();
1259 info.id = property_name+context;
1260 info.obj_id = property;
1262 return _mapInfo.insert(
1263 MapInfoT::value_type(property, info)).first->second;
1267 bool DotFileGeneratorGraphOp::hasInfo(void * handler) const
1269 MapInfoT::const_iterator iter = _mapInfo.find(handler);
1271 return iter != _mapInfo.end();
1274 bool DotFileGeneratorGraphOp::hasEdge(const Info& src, const Info& dst) const
1276 PairObjIdsT edge = std::make_pair(src.obj_id, dst.obj_id);
1278 return _edges.find(edge) != _edges.end();
1281 bool DotFileGeneratorGraphOp::makeEdge(const Info& src, const Info& dst)
1283 PairObjIdsT edge = std::make_pair(src.obj_id, dst.obj_id);
1285 return !_edges.insert(edge).second;
1288 std::ofstream &DotFileGeneratorGraphOp::initialize()
1290 if(!_spStream)
1292 _spStream.reset(new std::ofstream(_filename.c_str()));
1294 std::ofstream& stream = *_spStream;
1296 Colors core_colors, attachment_colors, material_colors;
1297 Colors state_chunk_colors, property_colors;
1299 core_colors .add("set312", 1, 12);
1300 core_colors .add("spectral11", 1, 11);
1301 attachment_colors .add("blues9", 3, 6);
1302 material_colors .add("purd9", 5, 7);
1303 state_chunk_colors.add("greens9", 1, 8);
1304 property_colors .add("oranges9", 1, 9);
1306 _colors["Core"] = core_colors;
1307 _colors["Attachment"] = attachment_colors;
1308 _colors["Material"] = material_colors;
1309 _colors["StateChunk"] = state_chunk_colors;
1310 _colors["Property"] = property_colors;
1312 stream << "digraph G {" << std::endl;
1314 _space++;
1316 if(_size.length() > 0)
1317 stream << space() << "Size=" << "\"" << _size << "\";" << std::endl;
1319 if(_ranksep.length() > 0)
1320 stream << space() << "ranksep=" << _ranksep << ";" << std::endl;
1322 if(_nodesep.length() > 0)
1323 stream << space() << "nodesep=" << _nodesep << ";" << std::endl;
1325 if(_graph_attributes.length() > 0)
1326 stream << space() << _graph_attributes << std::endl;
1329 return *_spStream;
1332 void DotFileGeneratorGraphOp::deinitialize(void)
1334 BOOST_FOREACH(const PairInfoT& edge, _dotted_edges)
1336 DefineDottedEdge(edge.first, edge.second, false);
1339 if(_spStream)
1341 std::ofstream& stream = *_spStream;
1343 stream << "}" << std::endl;
1344 stream << std::flush;
1345 stream.close();
1349 std::string DotFileGeneratorGraphOp::space(void)
1351 std::string sp("");
1353 for(UInt32 i = 0; i < _space; ++i)
1354 sp += " ";
1356 return sp;
1359 const DotFileGeneratorGraphOp::BrewerColor& DotFileGeneratorGraphOp::getColor(
1360 const std::string &domain,
1361 const std::string &name)
1363 MapUsedColorsT::const_iterator iter = _usedColors.find(name);
1365 if(iter != _usedColors.end())
1367 return iter->second;
1369 else
1371 return
1372 _usedColors.insert(
1373 MapUsedColorsT::value_type(
1374 name,
1375 _colors[domain].color())).first->second;
1379 void DotFileGeneratorGraphOp::OpenGroup(bool rank)
1381 std::ofstream &stream = initialize();
1383 stream << space()
1384 << "{" << std::endl;
1386 _space++;
1388 if(!_no_ranks && rank)
1390 stream << space()
1391 << "rank = same;"
1392 << std::endl;
1396 void DotFileGeneratorGraphOp::CloseGroup(void)
1398 std::ofstream& stream = initialize();
1400 _space--;
1402 stream << space()
1403 << "}" << std::endl;
1406 void DotFileGeneratorGraphOp::DefineNode(const Info &info)
1408 std::ofstream &stream = initialize();
1410 stream << space()
1411 << info.name << " "
1412 << "["
1413 << "label=\"" << info.label << "\"" << ","
1414 << "shape=box" << ","
1415 << "style=filled" << ","
1416 << "color=black" << ","
1417 << "fillcolor=gold1" << ","
1418 << "width=2.0,height=0.8"
1419 << "];"
1420 << std::endl;
1423 void DotFileGeneratorGraphOp::DefineCore(const Info &info)
1425 std::ofstream &stream = initialize();
1427 const BrewerColor &color = getColor("Core", info.id);
1429 stream << space()
1430 << info.name << " "
1431 << "["
1432 << "label=\"" << info.label << "\"" << ","
1433 << "shape=octagon" << ","
1434 << "style=filled" << ","
1435 << "colorscheme=" << color.scheme << ","
1436 << "color=black" << ","
1437 << "fillcolor=" << color.number << ",";
1439 if(!info.fontcolor.empty())
1440 stream << "fontcolor=\"" << info.fontcolor << "\"" << ",";
1442 stream << "width=2.0,height=0.8"
1443 << "];"
1444 << std::endl;
1447 void DotFileGeneratorGraphOp::DefineAttachment(const Info &info)
1449 std::ofstream &stream = initialize();
1451 const BrewerColor &color = getColor("Attachment", info.id);
1453 stream << space()
1454 << info.name << " "
1455 << "["
1456 << "label=\"" << info.label << "\"" << ","
1457 << "shape=ellipse" << ","
1458 << "style=filled" << ","
1459 << "colorscheme=" << color.scheme << ","
1460 << "color=black" << ","
1461 << "fillcolor=" << color.number << ","
1462 << "width=2.0,height=0.8"
1463 << "];"
1464 << std::endl;
1467 void DotFileGeneratorGraphOp::DefineMaterial(const Info &info)
1469 std::ofstream &stream = initialize();
1471 const BrewerColor &color = getColor("Material", info.id);
1473 stream << space()
1474 << info.name << " "
1475 << "["
1476 << "label=\"" << info.label << "\"" << ","
1477 << "shape=hexagon" << ","
1478 << "style=filled" << ","
1479 << "colorscheme=" << color.scheme << ","
1480 << "color=black" << ","
1481 << "fillcolor=" << color.number << ","
1482 << "width=2.0,height=0.8"
1483 << "];"
1484 << std::endl;
1487 void DotFileGeneratorGraphOp::DefineMatrix(const Info &info)
1489 std::ofstream &stream = initialize();
1491 stream << space()
1492 << info.name << " "
1493 << "["
1494 << "label=\"" << info.label << "\"" << ","
1495 << "shape=Mcircle" << ","
1496 << "style=filled" << ","
1497 << "color=black" << ","
1498 << "fillcolor=dodgerblue" << ","
1499 << "width=0.8,height=0.8"
1500 << "];"
1501 << std::endl;
1504 void DotFileGeneratorGraphOp::DefineImage(const Info &info)
1506 std::ofstream &stream = initialize();
1508 stream << space()
1509 << info.name << " "
1510 << "["
1511 << "label=\"" << info.label << "\"" << ","
1512 << "shape=Msquare" << ","
1513 << "style=filled" << ","
1514 << "color=black" << ","
1515 << "fillcolor=yellow" << ","
1516 << "width=2.0,height=0.8"
1517 << "];"
1518 << std::endl;
1521 void DotFileGeneratorGraphOp::DefineStateChunk(const Info &info)
1523 std::ofstream &stream = initialize();
1525 const BrewerColor &color = getColor("StateChunk", info.id);
1527 stream << space()
1528 << info.name << " "
1529 << "["
1530 << "label=\"" << info.label << "\"" << ","
1531 << "shape=parallelogram" << ","
1532 << "style=filled" << ","
1533 << "colorscheme=" << color.scheme << ","
1534 << "color=black" << ","
1535 << "fillcolor=" << color.number << ","
1536 << "width=2.0,height=0.8"
1537 << "];"
1538 << std::endl;
1541 void DotFileGeneratorGraphOp::DefineProperty(const Info &info)
1543 std::ofstream &stream = initialize();
1545 const BrewerColor &color = getColor("Property", info.id);
1547 stream << space()
1548 << info.name << " "
1549 << "["
1550 << "label=\"" << info.label << "\"" << ","
1551 << "shape=Mdiamond" << ","
1552 << "style=filled" << ","
1553 << "colorscheme=" << color.scheme << ","
1554 << "color=black" << ","
1555 << "fillcolor=" << color.number << ","
1556 << "width=2.0,height=1.5"
1557 << "];"
1558 << std::endl;
1561 void DotFileGeneratorGraphOp::DefineEtceteraNode(const Info &info)
1563 std::ofstream &stream = initialize();
1565 stream << space()
1566 << info.name << " "
1567 << "["
1568 << "label=\"" << info.label << "\"" << ","
1569 << "shape=box" << ","
1570 << "style=filled" << ","
1571 << "color=black" << ","
1572 << "fillcolor=firebrick1" << ","
1573 << "width=2.0,height=0.8"
1574 << "];"
1575 << std::endl;
1578 void DotFileGeneratorGraphOp::DefineHoldingEdge(const Info &src_info,
1579 const Info &dst_info)
1581 if(makeEdge(src_info, dst_info))
1582 return;
1584 std::ofstream &stream = initialize();
1586 stream << space()
1587 << src_info.name << " "
1588 << "->" << " "
1589 << dst_info.name << " "
1590 << "["
1591 << "dir=both" << ","
1592 << "arrowtail=diamond" << ","
1593 << "weight=2"
1594 << "];"
1595 << std::endl;
1598 void DotFileGeneratorGraphOp::DefineNodeEdge(const Info &parent_info,
1599 const Info &node_info )
1601 if(makeEdge(parent_info, node_info))
1602 return;
1604 std::ofstream &stream = initialize();
1606 stream << space()
1607 << parent_info.name << " "
1608 << "->" << " "
1609 << node_info.name << " "
1610 << "["
1611 << "penwidth=3.0" << ","
1612 << "arrowsize=2.0" << ","
1613 << "weight=8"
1614 << "];"
1615 << std::endl;
1618 void DotFileGeneratorGraphOp::DefineCoreEdge(const Info &node_info,
1619 const Info &core_info)
1621 if(makeEdge(node_info, core_info))
1622 return;
1624 std::ofstream &stream = initialize();
1626 stream << space()
1627 << node_info.name << " "
1628 << "->" << " "
1629 << core_info.name << " "
1630 << "["
1631 << "dir=both" << ","
1632 << "arrowtail=diamond" << ","
1633 << "weight=4"
1634 << "];"
1635 << std::endl;
1638 void DotFileGeneratorGraphOp::DefineAttachmentEdge(const Info &node_info,
1639 const Info &att_info)
1641 if(makeEdge(node_info, att_info))
1642 return;
1644 std::ofstream &stream = initialize();
1646 stream << space()
1647 << node_info.name << " "
1648 << "->" << " "
1649 << att_info.name << " "
1650 << "["
1651 << "style=dotted" << ","
1652 << "arrowhead=vee" << ","
1653 << "weight=2"
1654 << "];"
1655 << std::endl;
1658 void DotFileGeneratorGraphOp::DefineSimpleEdge(
1659 const Info &src_info,
1660 const Info &dst_info,
1661 bool constraint,
1662 std::string attribute )
1664 if(makeEdge(src_info, dst_info))
1665 return;
1667 std::ofstream &stream = initialize();
1669 stream << space()
1670 << src_info.name << " "
1671 << "->" << " "
1672 << dst_info.name << " "
1673 << "["
1674 << "arrowhead=vee" << ",";
1676 if(!constraint)
1677 stream << "constraint=false" << ",";
1679 if(!attribute.empty())
1680 stream << attribute << ",";
1682 stream << "weight=1"
1683 << "];"
1684 << std::endl;
1687 void DotFileGeneratorGraphOp::DefineDottedEdge(
1688 const Info &src_info,
1689 const Info &dst_info,
1690 bool constraint,
1691 std::string attribute )
1693 if(makeEdge(src_info, dst_info))
1694 return;
1696 std::ofstream &stream = initialize();
1698 stream << space()
1699 << src_info.name << " "
1700 << "->" << " "
1701 << dst_info.name << " "
1702 << "["
1703 << "style=dotted" << ","
1704 << "arrowhead=vee" << ",";
1706 if(!constraint)
1707 stream << "constraint=false" << ",";
1709 if(!attribute.empty())
1710 stream << attribute << ",";
1712 stream << "weight=1"
1713 << "];"
1714 << std::endl;
1717 OSG_END_NAMESPACE