1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2008 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
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. *
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. *
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. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
40 #include <boost/foreach.hpp>
42 #include "OSGDotFileGeneratorGraphOp.h"
43 #include "OSGContainerCollection.h"
44 #include "OSGGraphOpFactory.h"
46 #include "OSGMaterialGroup.h"
47 #include "OSGMaterialChunkOverrideGroup.h"
48 #include "OSGNameAttachment.h"
49 #include "OSGDistanceLOD.h"
50 #include "OSGScreenLOD.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.
74 static bool registerOp(void)
76 GraphOpRefPtr newOp
= DotFileGeneratorGraphOp::create();
78 GraphOpFactory::the()->registerOp(newOp
);
82 static OSG::StaticInitFuncWrapper
registerOpWrapper(registerOp
);
86 DotFileGeneratorGraphOp::Info::Info(void) :
97 DotFileGeneratorGraphOp::Info::Info(const Info
&other
) :
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
)
119 fontcolor
= rhs
.fontcolor
;
121 finished
= rhs
.finished
;
126 DotFileGeneratorGraphOp::BrewerColor::BrewerColor(const std::string
&schemeIn
,
127 const std::string
&numberIn
) :
133 DotFileGeneratorGraphOp::BrewerColor::~BrewerColor(void)
137 const DotFileGeneratorGraphOp::BrewerColor
&
138 DotFileGeneratorGraphOp::Colors::color(void) const
140 if (_current
>= _colors
.size())
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
,
153 for (UInt32 i
= start
; i
<= end
; ++i
)
155 std::stringstream number
;
157 _colors
.push_back(BrewerColor(scheme
, number
.str()));
161 DotFileGeneratorGraphOp::Colors::Colors(void) :
167 DotFileGeneratorGraphOp::Colors::~Colors(void)
171 const char *DotFileGeneratorGraphOp::getClassname(void)
173 return "DotFileGeneratorGraphOp";
176 DotFileGeneratorGraphOp::DotFileGeneratorGraphOp(const char* name
) :
178 _filename("out.dot"),
179 _include_attachment(true),
180 _no_name_attachments(true),
182 _max_node_children(-1),
186 _graph_attributes(""),
196 _integral_prop_cnt(0),
202 _suppressed_derived(),
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
)
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
);
230 ps("ranksep", _ranksep
);
231 ps("nodesep", _nodesep
);
232 ps("graph_attributes", _graph_attributes
);
234 std::string out
= ps
.getUnusedParams();
237 FWARNING(("DotFileGeneratorGraphOp doesn't have parameters '%s'\n.",
242 std::string
DotFileGeneratorGraphOp::usage(void)
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
)
262 _suppressed_derived
.push_back(t
);
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())
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
))
297 DotFileGeneratorGraphOp::~DotFileGeneratorGraphOp(void)
302 Action::ResultE
DotFileGeneratorGraphOp::traverseEnter(Node
* const node
)
304 if(isInExcludeList(node
))
307 Node
* parent
= node
->getParent();
308 NodeCore
* core
= node
->getCore();
310 if(_max_node_children
> 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;
322 EtceteraInfo(parent
->getNChildren() - _max_node_children
);
324 DefineEtceteraNode(node_info
);
325 DefineNodeEdge(parent_info
, node_info
);
331 const Info
&node_info
= NodeInfo(node
);
332 const Info
&core_info
= CoreInfo(core
);
334 bool suppressed
= isSuppressed(core
->getType());
339 DefineNode(node_info
);
343 DefineCore(core_info
);
344 DefineCoreEdge(node_info
, core_info
);
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
);
363 DefineNodeEdge(NodeInfo(parent
), node_info
);
366 return Action::Continue
;
369 void DotFileGeneratorGraphOp::HandleMaterial( NodeCore
* const core
,
372 Material
*mat
= NULL
;
373 MaterialGroup
*mgrp
= dynamic_cast<MaterialGroup
*>(core
);
377 mat
= mgrp
->getMaterial();
381 MaterialChunkOverrideGroup
*mcogrp
=
382 dynamic_cast<MaterialChunkOverrideGroup
*>(core
);
386 mat
= mcogrp
->getMaterial();
390 Geometry
*geom
= dynamic_cast<Geometry
*>(core
);
394 mat
= geom
->getMaterial();
401 bool suppressed
= isSuppressed(mat
->getType());
408 const Info
&mat_info
= MaterialInfo(mat
);
410 DefineMaterial(mat_info
);
411 DefineSimpleEdge(info
, mat_info
);
415 HandleChunkMaterial (mat
, mat_info
);
416 HandleSwitchMaterial (mat
, mat_info
);
417 HandleMultiPassMaterial(mat
, mat_info
);
421 void DotFileGeneratorGraphOp::HandleTransform( NodeCore
* const core
,
424 Transform
*trafo
= dynamic_cast<Transform
*>(core
);
428 void *handler
= &const_cast<Matrix
&>(trafo
->getMatrix());
430 if(!hasInfo(handler
))
434 Info mat_info
= MatrixInfo(trafo
->getMatrix(), handler
);
436 DefineMatrix(mat_info
);
437 DefineSimpleEdge(info
, mat_info
);
444 void DotFileGeneratorGraphOp::HandleGeometry( NodeCore
* const core
,
447 Geometry
*geom
= dynamic_cast<Geometry
*>(core
);
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
);
570 void DotFileGeneratorGraphOp::HandleTextureChunk(
571 StateChunk
* const chunk
,
574 TextureObjChunk
*textureobjchunk
= dynamic_cast<TextureObjChunk
*>(chunk
);
578 Image
*image
= textureobjchunk
->getImage();
582 bool suppressed
= isSuppressed(image
->getType());
589 const Info
&image_info
= ImageInfo(image
);
591 DefineMatrix(image_info
);
592 DefineSimpleEdge(info
, image_info
);
599 void DotFileGeneratorGraphOp::HandleLight( NodeCore
* const core
,
602 Light
*light
= dynamic_cast<Light
*>(core
);
606 Node
*beacon
= light
->getBeacon();
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
,
621 VisitSubTree
*visitSubTree
= dynamic_cast<VisitSubTree
*>(core
);
625 Node
*subTreeRoot
= visitSubTree
->getSubTreeRoot();
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
);
638 traverse(subTreeRoot
);
644 void DotFileGeneratorGraphOp::HandleBeaconedChunk(
645 StateChunk
* const chunk
,
648 ClipPlaneChunk
*clippl
= dynamic_cast<ClipPlaneChunk
*>(chunk
);
652 Node
*beacon
= clippl
->getBeacon();
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
);
667 Node
*beacon
= light
->getBeacon();
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
,
683 SwitchMaterial
*switchMat
= dynamic_cast<SwitchMaterial
*>(material
);
687 UInt32 num
= switchMat
->editMFMaterials()->size();
689 for(UInt32 i
= 0; i
< num
; ++i
)
691 Material
*mat
= switchMat
->getMaterial(i
);
695 bool suppressed
= isSuppressed(mat
->getType());
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());
712 HandleChunkMaterial (mat
, mat_info
);
713 HandleSwitchMaterial (mat
, mat_info
);
714 HandleMultiPassMaterial(mat
, mat_info
);
720 void DotFileGeneratorGraphOp::HandleChunkMaterial(
721 Material
* const material
,
724 ChunkMaterial
*chunkMat
= dynamic_cast<ChunkMaterial
*>(material
);
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
;
742 bool suppressed
= isSuppressed(statechunk
->getType());
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
);
760 void DotFileGeneratorGraphOp::HandleMultiPassMaterial(
761 Material
* const material
,
764 MultiPassMaterial
*multiPassMat
=
765 dynamic_cast<MultiPassMaterial
*>(material
);
769 UInt32 num
= multiPassMat
->editMFMaterials()->size();
771 for(UInt32 i
= 0; i
< num
; ++i
)
773 Material
*mat
= multiPassMat
->getMaterials(i
);
777 bool suppressed
= isSuppressed(mat
->getType());
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());
794 HandleChunkMaterial(mat
, mat_info
);
795 HandleSwitchMaterial(mat
, mat_info
);
796 HandleMultiPassMaterial(mat
, mat_info
);
803 void DotFileGeneratorGraphOp::HandleAttachment(
804 AttachmentContainer
* const fc
,
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
;
818 mapIt
= pAttMap
->getValue().begin();
819 mapEnd
= pAttMap
->getValue().end();
821 for(; mapIt
!= mapEnd
; ++mapIt
)
823 AttachmentUnrecPtr att
= mapIt
->second
;
827 if (_no_name_attachments
&&
828 Name::getClassType().getGroupId() == att
->getGroupId())
833 if(ContainerCollection::getClassType().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
=
844 MFUnrecFieldContainerPtr::const_iterator fEnd
=
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
);
866 mapIt
= pAttMap
->getValue().begin();
867 mapEnd
= pAttMap
->getValue().end();
869 for(; mapIt
!= mapEnd
; ++mapIt
)
871 AttachmentUnrecPtr att
= mapIt
->second
;
874 if(_no_name_attachments
&&
875 Name::getClassType().getGroupId() == att
->getGroupId())
880 const Info
&attachment_info
= AttachmentInfo(att
);
882 DefineAttachment(attachment_info
);
883 DefineAttachmentEdge(info
, attachment_info
);
885 if(ContainerCollection::getClassType().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
=
896 MFUnrecFieldContainerPtr::const_iterator fEnd
=
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
);
906 const Info
& node_info
= NodeInfo(node
);
907 DefineHoldingEdge(attachment_info
, node_info
);
919 Action::ResultE
DotFileGeneratorGraphOp::traverseLeave(
921 Action::ResultE res
)
926 DotFileGeneratorGraphOp::Info
&DotFileGeneratorGraphOp::NodeInfo(
929 MapInfoT::iterator iter
= _mapInfo
.find(node
);
931 if(iter
!= _mapInfo
.end())
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
);
949 info
.cnt
= _node_cnt
;
950 info
.name
= name
.str();
951 info
.label
= label
.str();
952 info
.id
= node
->getTypeName();
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())
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
);
985 info
.cnt
= _core_cnt
;
986 info
.name
= name
.str();
987 info
.label
= label
.str();
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
;
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
);
1023 label
<< "\\n" << attName
->getFieldPtr()->getValue().c_str();
1027 info
.cnt
= _attachment_cnt
;
1028 info
.name
= name
.str();
1029 info
.label
= label
.str();
1030 info
.id
= attachment_name
;
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
;
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
);
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
,
1078 MapInfoT::iterator iter
= _mapInfo
.find(handler
);
1080 if(iter
!= _mapInfo
.end())
1082 return iter
->second
;
1088 std::stringstream name
, label
;
1090 name
<< "Matrix_" << _matrix_cnt
;
1091 label
<< "Matrix" << " " << _matrix_cnt
;
1095 info
.cnt
= _matrix_cnt
;
1096 info
.name
= name
.str();
1097 info
.label
= label
.str();
1099 info
.obj_id
= handler
;
1101 return _mapInfo
.insert(
1102 MapInfoT::value_type(handler
, info
)).first
->second
;
1106 DotFileGeneratorGraphOp::Info
DotFileGeneratorGraphOp::EtceteraInfo(
1109 std::stringstream name
, label
;
1112 label
<< "Etcetera";
1113 label
<< "\\n" << "number = " << number
;
1118 info
.name
= name
.str();
1119 info
.label
= label
.str();
1120 info
.id
= "Etcetera";
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
;
1139 std::string image_name
= image
->getName();
1141 std::stringstream name
, label
;
1143 name
<< "Image_" << _image_cnt
;
1144 label
<< "Image" << " " << _image_cnt
;
1148 info
.cnt
= _image_cnt
;
1149 info
.name
= name
.str();
1150 info
.label
= label
.str();
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
;
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
);
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
;
1207 _integral_prop_cnt
++;
1209 std::string property_name
= property
->getTypeName();
1211 std::stringstream name
, label
;
1213 name
<< "GeoIntegralProperty_" << _integral_prop_cnt
;
1215 label
<< "\\n" << property_name
<< " " << _integral_prop_cnt
;
1216 label
<< "\\n" << "size = " << property
->size();
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
;
1245 std::string property_name
= property
->getTypeName();
1247 std::stringstream name
, label
;
1249 name
<< "GeoVectorProperty_" << _vector_prop_cnt
;
1251 label
<< "\\n" << property_name
<< " " << _vector_prop_cnt
;
1252 label
<< "\\n" << "size = " << property
->size();
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()
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
;
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
;
1332 void DotFileGeneratorGraphOp::deinitialize(void)
1334 BOOST_FOREACH(const PairInfoT
& edge
, _dotted_edges
)
1336 DefineDottedEdge(edge
.first
, edge
.second
, false);
1341 std::ofstream
& stream
= *_spStream
;
1343 stream
<< "}" << std::endl
;
1344 stream
<< std::flush
;
1349 std::string
DotFileGeneratorGraphOp::space(void)
1353 for(UInt32 i
= 0; i
< _space
; ++i
)
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
;
1373 MapUsedColorsT::value_type(
1375 _colors
[domain
].color())).first
->second
;
1379 void DotFileGeneratorGraphOp::OpenGroup(bool rank
)
1381 std::ofstream
&stream
= initialize();
1384 << "{" << std::endl
;
1388 if(!_no_ranks
&& rank
)
1396 void DotFileGeneratorGraphOp::CloseGroup(void)
1398 std::ofstream
& stream
= initialize();
1403 << "}" << std::endl
;
1406 void DotFileGeneratorGraphOp::DefineNode(const Info
&info
)
1408 std::ofstream
&stream
= initialize();
1413 << "label=\"" << info
.label
<< "\"" << ","
1414 << "shape=box" << ","
1415 << "style=filled" << ","
1416 << "color=black" << ","
1417 << "fillcolor=gold1" << ","
1418 << "width=2.0,height=0.8"
1423 void DotFileGeneratorGraphOp::DefineCore(const Info
&info
)
1425 std::ofstream
&stream
= initialize();
1427 const BrewerColor
&color
= getColor("Core", info
.id
);
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"
1447 void DotFileGeneratorGraphOp::DefineAttachment(const Info
&info
)
1449 std::ofstream
&stream
= initialize();
1451 const BrewerColor
&color
= getColor("Attachment", info
.id
);
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"
1467 void DotFileGeneratorGraphOp::DefineMaterial(const Info
&info
)
1469 std::ofstream
&stream
= initialize();
1471 const BrewerColor
&color
= getColor("Material", info
.id
);
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"
1487 void DotFileGeneratorGraphOp::DefineMatrix(const Info
&info
)
1489 std::ofstream
&stream
= initialize();
1494 << "label=\"" << info
.label
<< "\"" << ","
1495 << "shape=Mcircle" << ","
1496 << "style=filled" << ","
1497 << "color=black" << ","
1498 << "fillcolor=dodgerblue" << ","
1499 << "width=0.8,height=0.8"
1504 void DotFileGeneratorGraphOp::DefineImage(const Info
&info
)
1506 std::ofstream
&stream
= initialize();
1511 << "label=\"" << info
.label
<< "\"" << ","
1512 << "shape=Msquare" << ","
1513 << "style=filled" << ","
1514 << "color=black" << ","
1515 << "fillcolor=yellow" << ","
1516 << "width=2.0,height=0.8"
1521 void DotFileGeneratorGraphOp::DefineStateChunk(const Info
&info
)
1523 std::ofstream
&stream
= initialize();
1525 const BrewerColor
&color
= getColor("StateChunk", info
.id
);
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"
1541 void DotFileGeneratorGraphOp::DefineProperty(const Info
&info
)
1543 std::ofstream
&stream
= initialize();
1545 const BrewerColor
&color
= getColor("Property", info
.id
);
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"
1561 void DotFileGeneratorGraphOp::DefineEtceteraNode(const Info
&info
)
1563 std::ofstream
&stream
= initialize();
1568 << "label=\"" << info
.label
<< "\"" << ","
1569 << "shape=box" << ","
1570 << "style=filled" << ","
1571 << "color=black" << ","
1572 << "fillcolor=firebrick1" << ","
1573 << "width=2.0,height=0.8"
1578 void DotFileGeneratorGraphOp::DefineHoldingEdge(const Info
&src_info
,
1579 const Info
&dst_info
)
1581 if(makeEdge(src_info
, dst_info
))
1584 std::ofstream
&stream
= initialize();
1587 << src_info
.name
<< " "
1589 << dst_info
.name
<< " "
1591 << "dir=both" << ","
1592 << "arrowtail=diamond" << ","
1598 void DotFileGeneratorGraphOp::DefineNodeEdge(const Info
&parent_info
,
1599 const Info
&node_info
)
1601 if(makeEdge(parent_info
, node_info
))
1604 std::ofstream
&stream
= initialize();
1607 << parent_info
.name
<< " "
1609 << node_info
.name
<< " "
1611 << "penwidth=3.0" << ","
1612 << "arrowsize=2.0" << ","
1618 void DotFileGeneratorGraphOp::DefineCoreEdge(const Info
&node_info
,
1619 const Info
&core_info
)
1621 if(makeEdge(node_info
, core_info
))
1624 std::ofstream
&stream
= initialize();
1627 << node_info
.name
<< " "
1629 << core_info
.name
<< " "
1631 << "dir=both" << ","
1632 << "arrowtail=diamond" << ","
1638 void DotFileGeneratorGraphOp::DefineAttachmentEdge(const Info
&node_info
,
1639 const Info
&att_info
)
1641 if(makeEdge(node_info
, att_info
))
1644 std::ofstream
&stream
= initialize();
1647 << node_info
.name
<< " "
1649 << att_info
.name
<< " "
1651 << "style=dotted" << ","
1652 << "arrowhead=vee" << ","
1658 void DotFileGeneratorGraphOp::DefineSimpleEdge(
1659 const Info
&src_info
,
1660 const Info
&dst_info
,
1662 std::string attribute
)
1664 if(makeEdge(src_info
, dst_info
))
1667 std::ofstream
&stream
= initialize();
1670 << src_info
.name
<< " "
1672 << dst_info
.name
<< " "
1674 << "arrowhead=vee" << ",";
1677 stream
<< "constraint=false" << ",";
1679 if(!attribute
.empty())
1680 stream
<< attribute
<< ",";
1682 stream
<< "weight=1"
1687 void DotFileGeneratorGraphOp::DefineDottedEdge(
1688 const Info
&src_info
,
1689 const Info
&dst_info
,
1691 std::string attribute
)
1693 if(makeEdge(src_info
, dst_info
))
1696 std::ofstream
&stream
= initialize();
1699 << src_info
.name
<< " "
1701 << dst_info
.name
<< " "
1703 << "style=dotted" << ","
1704 << "arrowhead=vee" << ",";
1707 stream
<< "constraint=false" << ",";
1709 if(!attribute
.empty())
1710 stream
<< attribute
<< ",";
1712 stream
<< "weight=1"