GithubHelp home page GithubHelp logo

hpp2plantuml's Introduction

hpp2plantuml - Convert C++ header files to PlantUML

Motivation

The purpose of this tool is to convert C++ header files to a UML representation in PlantUML syntax that can be used to generate diagrams with PlantUML.

PlantUML is a program rendering UML diagrams from plain text inputs using an expressive language.

This package generates the text input to PlantUML from C++ header files. Its ambition is limited but it should produce reasonable conversion for simple class hierarchies. It aims at supporting:

  • class members with properties (private, method, protected), methods with basic qualifiers (static, abstract),
  • inheritance relationships,
  • aggregation relationships (very basic support).
  • dependency relationships

The package relies on the CppHeaderParser package for parsing of C++ header files.

Usage

The hpp2plantuml package can be used from the command line or as a module in other applications.

Command line

The command line usage is (hpp2plantuml --help):

usage: hpp2plantuml [-h] -i HEADER-FILE [-o FILE] [-d] [-t JINJA-FILE]
                    [--version]

hpp2plantuml tool.

optional arguments:
  -h, --help            show this help message and exit
  -i HEADER-FILE, --input-file HEADER-FILE
                        input file (must be quoted when using wildcards)
  -o FILE, --output-file FILE
                        output file
  -d, --enable-dependency
                        Extract dependency relationships from method arguments
  -t JINJA-FILE, --template-file JINJA-FILE
                        path to jinja2 template file
  --version             show program's version number and exit

Input files are added using the -i option. Inputs can be full file paths or include wildcards. Note that double quotes are required when using wildcards. The output file is selected with the -o option. The output is a text file following the PlantUML syntax.

For instance, the following command will generate an input file for PlantUML (output.puml) from several header files.

hpp2plantuml -i File_1.hpp -i "include/Helper_*.hpp" -o output.puml

To customize the output PlantUML file, templates can be used (using the -t parameter):

hpp2plantuml -i File_1.hpp -i "include/Helper_*.hpp" -o output.puml -t template.puml

This will use the template.puml file as template. Templates follow the jinja syntax. For instance, to add a preamble to the PlantUML output, the template file may contain:

{% extends 'default.puml' %}

{% block preamble %}
title "This is a title"
skinparam backgroundColor #EEEBDC
skinparam handwritten true
{% endblock %}

This will inherit from the default template and override the preamble only.

Module

To use as a module, simply import hpp2plantuml. The CreatePlantUMLFile function can then be used to create a PlantUML file from a set of input files. Alternatively, the Diagram object can be used directly to build internal objects (from files or strings). The Diagram.render() method can be used to produce a string output instead of writing to a text file. See the API documentation for more details.

Installation

Using pip

The package is available on PyPi and can be installed using pip:

pip install hpp2plantuml

From source

The code uses setuptools, so it can be built using:

python setup.py install

To build the documentation, run:

python setup.py sphinx

To run the tests, run:

python setup.py test

The full documentation is available via:

hpp2plantuml's People

Contributors

cheoljoo avatar rockkoca avatar themmj avatar thibaultmarin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hpp2plantuml's Issues

Problem parsing std::function member

Given this input header:

#pragma once

#include <functional>
#include <memory>


class Foo
{
    std::function<std::shared_ptr<BlockFinder>(void)> const m_startBlockFinder;
    std::shared_ptr<BlockFinder> m_blockFinder;
};

and parsing it with:

hpp2plantuml -i hpp2uml-bracket-bug.hpp

I get (shortened for brevity):

@startuml
class Foo {
	->() : std::function<std::shared_ptr<BlockFinder {query}
	-m_blockFinder : std::shared_ptr<BlockFinder>
}
@enduml

It looks like m_startBlockFinder got interpreted as a method with name > instead of being recognized as a member.

Offer title option

Please, offer an optional argument to add a title.

For example, the option can be called -t or --title and requires a string, possible with escaped spaces or enclosed in two single or two double quotes.

The result will be that a line starting with title and this string (without escaping of spaces or enclosing quotes) is added to the generated PlantUML file.

Support for template signatures

Given this header:

template<
    typename Key,
    typename Value,
    typename CacheStrategy = CacheStrategy::LeastRecentlyUsed<Key>
>
class Cache
{};

I get this result:

@startuml
class Cache <template<typename Key, typename Value, typename CacheStrategy=CacheStrategy::LeastRecentlyUsed<Key>>> {
}
@enduml

This is rendered as:

template-signature

I would have expected something more formal UML, like here. I.e., I would expect something like:

@startuml
class Cache <Key, Value, CacheStrategy>{
}
@enduml

template-signature

I'm not sure what to do about the default value for template arguments.

Enums are not connected to classes which hold them

The relationship between enums and classes which have an attribute of their type is not present in the output.
I am not sure if this is intentional, if it is some kind of flag to enable this feature would be nice.

Minimal example:

echo '
enum ExampleEnum{
  A, B
};

class ExampleClass {
 public:
  ExampleEnum enum_attr;
};
' >  Example.h
hpp2plantuml -i Example.h -o hpp2plantuml
cat hpp2plantuml

Output (whitespace modified):

hpp2plantuml 0.7.1
@startuml
/' Objects '/
class ExampleClass {
	+enum_attr : ExampleEnum
}

enum ExampleEnum {
	A
	B
}

/' Inheritance relationships '/

/' Aggregation relationships '/

@enduml

Expected result:
An additional line under Aggregation relationships: ExampleClass *-- ExampleEnum

#defines in enumerator is causing error

It might be a corner case, but a corner case I am stumbling into right now.

The following snippet is causing an error and I am not sure if the #define should be ignored in the diagram or not.

enum class states
{
    #undef ID
    #define ID(x) x,
    state
};

#ifdef in enum causes CppParseError exception

enum class MyType : uint8_t {
    kFoo = 0,
    kBar
#ifdef UNIT_TESTS
    , kTest
#endif
};

Causes

Traceback (most recent call last):
  File "/home/tlyngmo/.local/lib/python3.8/site-packages/CppHeaderParser/CppHeaderParser.py", line 2963, in __init__
    self._evaluate_stack()
  File "/home/tlyngmo/.local/lib/python3.8/site-packages/CppHeaderParser/CppHeaderParser.py", line 3397, in _evaluate_stack
    self._parse_enum()
  File "/home/tlyngmo/.local/lib/python3.8/site-packages/CppHeaderParser/CppHeaderParser.py", line 3583, in _parse_enum
    self._parse_enumerator_list(newEnum["values"])
  File "/home/tlyngmo/.local/lib/python3.8/site-packages/CppHeaderParser/CppHeaderParser.py", line 3655, in _parse_enumerator_list
    tok = self._next_token_must_be("}", ",", "=", "DBL_LBRACKET")
  File "/home/tlyngmo/.local/lib/python3.8/site-packages/CppHeaderParser/CppHeaderParser.py", line 3164, in _next_token_must_be
    raise self._parse_error((tok,), "' or '".join(tokenTypes))
CppHeaderParser.CppHeaderParser.CppParseError: unexpected '#ifdef UNIT_TESTS', expected '}' or ',' or '=' or 'DBL_LBRACKET'

Feature request: Represent arbitrary packages

Drawing packages (see section 'Packages' in the PlantUML doc) would make the final diagram for larger projects more readable.
These packages can be based on the directory structure but (in my opinion) they should not have to be.

My idea for the interface is a new argument to add a package based on a regular expression, all headers with a path which contains a match become part of a package.
This would allow for the most common case where a package matches exactly with a directory.
But it would also allow for more complicated situations where packages span over directories or one directory contains multiple packages (e.g. all classes with a certain prefix).

Example:

hpp2plantuml -i frontend/a.h -i frontend/b.h -i middleware/c.h -i backend/d.h \
--package "Front end" "frontend/" \
--package "Legacy code" "(middleware/c.h)|(backend/d.h)"

Some way of setting the package style (see section 'Packages style' in the PlantUML doc) would be a nice extra.

@thibaultmarin: If you dont want to do this, please tell me and I will make a pr when I find time for this.

Class enumerator is not connecting

When creating an enumerator in a class it is not connecting correctly in the final diagram. An example is shown below.

class TestClass{
    int var1 = 10;
    int var2 = 10;

    void method1(int a, float b);
    void method2();

    enum class EnumTest{
        e_test1,
        e_test2
    };
};

This results in the following puml code. Is seems like the added "." in front of TestClass::EnumTest is making the arrow point back to "TestClass" instead of the enumerator. By removing the "." the enumerator is pointing correctly.

@startuml
/' Objects '/
class TestClass {
	-var1 : int
	-var2 : int
	-method1(int a, float b) : void
	-method2() : void
}

enum TestClass::EnumTest {
	e_test1
	e_test2
}
/' Inheritance relationships '/
/' Aggregation relationships '/
/' Nested objects '/
.TestClass +-- .TestClass::EnumTest
@enduml

enum

Offer skin file option

Please, offer an optional argument to include a skin file.

For example, the option can be called -s or --skin-file and requires a valid path to a file. The file will contain skinparam settings and its path will be used after an !include command following directly the @startuml command at the top of in the generated PlantUML file.

Support initialization list

If a member variable is initialized with initialization list, it could not be recognized as an aggregation relationship.

Keep order of members

Hello,

Thank you for providing this useful tool!

I tried it on some headers and it is a good start but I noticed that the members seem to have a complete random order, neither alphabetical nor the order as defined in the original headers.

I think it would be helpful to keep the order as defined in the input headers.

As for reproducing the problem if it is code dependend. I ran:

hpp2plantuml -i 'indexed_bzip2/*.hpp' > ParallelBZ2Reader.puml

on indexed_bzip2.

KeyError: 'values'

I ran hpp2plantuml for a project and errors arose for three header files, the output was:

[1485] WARN unresolved _reference
Traceback (most recent call last):
  File "/usr/local/bin/hpp2plantuml", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 1112, in main
    CreatePlantUMLFile(args.input_files, args.output_file)
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 1080, in CreatePlantUMLFile
    diag.create_from_file_list(list(set(expand_file_list(file_list_c))))
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 768, in create_from_file_list
    flag_build_lists=True, flag_reset=True)
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 747, in _build_helper
    self.parse_objects(single_input, build_from_single)
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 860, in parse_objects
    self._objects.append(container_handler(obj))
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 32, in <lambda>
    ['enums', lambda objs: objs, lambda obj: Enum(obj)]
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 487, in __init__
    self.parse_members(header_enum)
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 497, in parse_members
    for value in header_enum['values']:
KeyError: 'values'

The script I use to run it is
https://github.com/nuspell/nuspell/blob/e18c81732a39ab5735659338333253c1969b0642/checks/hpp2plantuml.sh

or hpp2plantuml -i "src/nuspell/*.hxx" -o nuspell.puml for project https://github.com/nuspell/nuspell

Nested namespace with empty top namespace

If a namespace which contains a class is contained inside of a namespace which contains no classes, an error is thrown.

Minimal example:

hpp2plantuml --version
echo '
namespace first_ns::second_ns{
	class A{};
}
' > Example.h
hpp2plantuml -i Example.h

Output:

hpp2plantuml 0.8.0
Traceback (most recent call last):
  File "/usr/local/bin/hpp2plantuml", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 1474, in main
    flag_dep=args.flag_dep)
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 1434, in CreatePlantUMLFile
    diag_render = diag.render()
  File "/usr/local/lib/python3.6/dist-packages/hpp2plantuml/hpp2plantuml.py", line 1267, in render
    ns_obj_map[ns_parent].append(ns_obj_map[ns])
KeyError: 'first_ns'

If a class is added to the top namespace, no error is thrown and the correct result is produced:

namespace first_ns::second_ns{
	class A{};
}

namespace first_ns{
	class B{};
}

Problem parsing brace-or-equal initializer for class members

Hello, thanks for this great tool!
I found the following error while using the C++ brace-or-equal initializer

Code:

private:
  int a;
  int b{0};
  int c = {0};
  int d = 1;
};

Output:

@startuml

/' Objects '/

class A {
        -a : int
        -d : int
}

/' Inheritance relationships '/

/' Aggregation relationships '/

/' Dependency relationships '/

/' Nested objects '/

@enduml

concated namespace problem

Hello!

Thank you very much for this useful tool.

I found a little problem with namespaces.
From the following code:

namespace prefix::test::third{
	class MyClass{};
}

Your tool will create, with the command hpp2plantuml -i test.hpp -o test.puml, this output:

@startuml

/' Objects '/

namespace prefix {
	namespace prefix::test {
		namespace prefix::test::third {
			class MyClass {
			}
		}
	}
}

/' Inheritance relationships '/

/' Aggregation relationships '/

/' Nested objects '/

@enduml

I would expect an output like this:

@startuml

/' Objects '/

namespace prefix::test::third   {	
  class MyClass {
  }
}

/' Inheritance relationships '/

/' Aggregation relationships '/

/' Nested objects '/

@enduml

or like this:

@startuml

/' Objects '/

namespace prefix {
	namespace test {
		namespace third {
			class MyClass {
			}
		}
	}
}

/' Inheritance relationships '/

/' Aggregation relationships '/

/' Nested objects '/

@enduml

There is no possibility of parsing classes with Qt

The current version of the parser does not support Qt
CppHeaderParser.CppHeaderParser.CppParseError: Not able to parse my_class.h on line 9 evaluating ';': unexpected ';', expected ',' or '{'
Error around: Q_PROPERTY ( Priority priority READ priority WRITE setPriority NOTIFY priorityChanged ) public

Generate PlantUML for headers in multple directories

Hello There,

It's a great tool to automate the generation of UML class diagrams from headers. Currently, in my project, I have several directories and each contains headers in the below format.

├── App
 |   └── App.h
├── Demo
│   └── Runtime.h
└── client
    ├── client.h
    ├── client_app.h


Is there any way to provide the root directory path to generate the PlantUML code?

Ability to check dependency from #includes

Hi,

This is more of a question than an issue.

While testing the project I noticed that when the classes functions depends on another classes functions but nothing else and there is included header file it doesn't draw the dependency lines.

So my question is: is this on purpose that the project doesnt take into account included headerfiles? Or am I doing something wrong?
I do include the -d parameter.
hpp2plantuml -i Testheader1.hpp -i TestInterface1.hpp -i testheader2.hpp -d -o testdep.puml

Thank you!

help me convert this puml to png

$java -jar /home/auser/bin/plantuml.jar ndt.puml -tsvg
Error line 98 in file: ndt.puml
Some diagram description contains errors

@startuml

/' Objects '/

namespace pcl {
class NormalDistributionsTransform <template<typename PointSource, typename PointTarget>> {
+NormalDistributionsTransform()
+~NormalDistributionsTransform()
#point_hessian_ : Eigen::Matrix<double, 18, 6>
#point_gradient_ : Eigen::Matrix<double, 3, 6>
#h_ang_a2_ : Eigen::Vector3d
#h_ang_a3_ : Eigen::Vector3d
#h_ang_b2_ : Eigen::Vector3d
#h_ang_b3_ : Eigen::Vector3d
#h_ang_c2_ : Eigen::Vector3d
#h_ang_c3_ : Eigen::Vector3d
#h_ang_d1_ : Eigen::Vector3d
#h_ang_d2_ : Eigen::Vector3d
#h_ang_d3_ : Eigen::Vector3d
#h_ang_e1_ : Eigen::Vector3d
#h_ang_e2_ : Eigen::Vector3d
#h_ang_e3_ : Eigen::Vector3d
#h_ang_f1_ : Eigen::Vector3d
#h_ang_f2_ : Eigen::Vector3d
#h_ang_f3_ : Eigen::Vector3d
#j_ang_a_ : Eigen::Vector3d
#j_ang_b_ : Eigen::Vector3d
#j_ang_c_ : Eigen::Vector3d
#j_ang_d_ : Eigen::Vector3d
#j_ang_e_ : Eigen::Vector3d
#j_ang_f_ : Eigen::Vector3d
#j_ang_g_ : Eigen::Vector3d
#j_ang_h_ : Eigen::Vector3d
#target_cells_ : TargetGrid
#updateIntervalMT(double& a_l, double& f_l, double& g_l, double& a_u, double& f_u, double& g_u, double a_t, double f_t, double g_t) : bool
#auxilaryFunction_PsiMT(double a, double f_a, double f_0, double g_0, double mu) : double
#auxilaryFunction_dPsiMT(double g_a, double g_0, double mu) : double
#computeDerivatives(Eigen::Matrix<double, 6, 1>& score_gradient, Eigen::Matrix<double, 6, 6>& hessian, PointCloudSource& trans_cloud, Eigen::Matrix<double, 6, 1>& p, bool compute_hessian) : double
#computeStepLengthMT(const Eigen::Matrix<double, 6, 1>& x, Eigen::Matrix<double, 6, 1>& step_dir, double step_init, double step_max, double step_min, double& score, Eigen::Matrix<double, 6, 1>& score_gradient, Eigen::Matrix<double, 6, 6>& hessian, PointCloudSource& trans_cloud) : double
#gauss_d1_ : double
#gauss_d2_ : double
+getOulierRatio() : double {query}
+getStepSize() : double {query}
+getTransformationProbability() : double {query}
#outlier_ratio_ : double
#step_size_ : double
#trans_probability_ : double
#trialValueSelectionMT(double a_l, double f_l, double g_l, double a_u, double f_u, double g_u, double a_t, double f_t, double g_t) : double
#updateDerivatives(Eigen::Matrix<double, 6, 1>& score_gradient, Eigen::Matrix<double, 6, 6>& hessian, Eigen::Vector3d& x_trans, Eigen::Matrix3d& c_inv, bool compute_hessian) : double
+getResolution() : float {query}
#resolution_ : float
+getFinalNumIteration() : int {query}
#computeAngleDerivatives(Eigen::Matrix<double, 6, 1>& p, bool compute_hessian) : void
#computeHessian(Eigen::Matrix<double, 6, 6>& hessian, PointCloudSource& trans_cloud, Eigen::Matrix<double, 6, 1>& p) : void
#computePointDerivatives(Eigen::Vector3d& x, bool compute_hessian) : void
#computeTransformation(PointCloudSource& output) : void
#computeTransformation(PointCloudSource& output, const Eigen::Matrix4f& guess) : void
+{static} convertTransform(const Eigen::Matrix<double, 6, 1>& x, Eigen::Affine3f& trans) : void
+{static} convertTransform(const Eigen::Matrix<double, 6, 1>& x, Eigen::Matrix4f& trans) : void
#init() : void
+setInputTarget(const PointCloudTargetConstPtr& cloud) : void
+setOulierRatio(double outlier_ratio) : void
+setResolution(float resolution) : void
+setStepSize(double step_size) : void
#updateHessian(Eigen::Matrix<double, 6, 6>& hessian, Eigen::Vector3d& x_trans, Eigen::Matrix3d& c_inv) : void
}
}

namespace pcl {
class PCLBase <template> {
+PCLBase()
+PCLBase(const PCLBase& base)
+~PCLBase()
+getIndices() : IndicesConstPtr {query}
+getIndices() : IndicesPtr
+getInputCloud() : PointCloudConstPtr {query}
#input_ : PointCloudConstPtr
+operator[](size_t pos) : PointT& {query}
#deinitCompute() : bool
#fake_indices_ : bool
#initCompute() : bool
#use_indices_ : bool
#indices_ : pcl::IndicesPtr
+setIndices(pcl::IndicesPtr indices) : void
+setIndices(pcl::IndicesConstPtr indices) : void
+setIndices(const PointIndicesConstPtr& indices) : void
+setIndices(size_t row_start, size_t col_start, size_t nb_rows, size_t nb_cols) : void
+setInputCloud(const PointCloudConstPtr& cloud) : void
}
}

namespace pcl {
class PCL_EXPORTSPCLBasepcl::PCLPointCloud2 <template<>> {
+PCLBase()
+~PCLBase()
+getIndices() : IndicesPtr
+getInputCloud() : PCLPointCloud2ConstPtr
#input_ : PCLPointCloud2ConstPtr
#deinitCompute() : bool
#fake_indices_ : bool
#initCompute() : bool
#use_indices_ : bool
#x_idx_ : int
#y_idx_ : int
#z_idx_ : int
#indices_ : pcl::IndicesPtr
#x_field_name_ : std::string
#y_field_name_ : std::string
#z_field_name_ : std::string
#field_sizes_ : std::vector
+setIndices(pcl::IndicesPtr indices) : void
+setIndices(const PointIndicesConstPtr& indices) : void
+setInputCloud(const PCLPointCloud2ConstPtr& cloud) : void
}
}

namespace pcl {
abstract class Registration <template<typename PointSource, typename PointTarget, typename Scalar=float>> {
+PCL_DEPRECATED("[pcl::registration::Registration::setInputCloud] setInputCloud is deprecated. Please use setInputSource instead." ) void setInputCloud ( const PointCloudSourceConstPtr& cloud)
+PCL_DEPRECATED("[pcl::registration::Registration::getInputCloud] getInputCloud is deprecated. Please use getInputSource instead." ) PointCloudSourceConstPtr const getInputCloud ()
+Registration()
#function<void(const pcl::PointCloud& cloud_src, const std::vector& indices_src, const pcl::PointCloud& cloud_tgt, const std::vector& indices_tgt)
+~Registration()
#correspondence_estimation_ : CorrespondenceEstimationPtr
#correspondences_ : CorrespondencesPtr
+getSearchMethodTarget() : KdTreePtr {query}
#tree_ : KdTreePtr
+getSearchMethodSource() : KdTreeReciprocalPtr {query}
#tree_reciprocal_ : KdTreeReciprocalPtr
#final_transformation_ : Matrix4
+getFinalTransformation() : Matrix4
+getLastIncrementalTransformation() : Matrix4
#previous_transformation_ : Matrix4
#transformation_ : Matrix4
+getInputSource() : PointCloudSourceConstPtr
+getInputTarget() : PointCloudTargetConstPtr
#target_ : PointCloudTargetConstPtr
-point_representation_ : PointRepresentationConstPtr
#transformation_estimation_ : TransformationEstimationPtr
#converged_ : bool
#force_no_recompute_ : bool
#force_no_recompute_reciprocal_ : bool
+hasConverged() : bool
+initCompute() : bool
+initComputeReciprocal() : bool
+registerVisualizationCallback(boost::function& visualizerCallback) : bool
+removeCorrespondenceRejector(unsigned int i) : bool
#searchForNeighbors(const PointCloudSource& cloud, int index, std::vector& indices, std::vector& distances) : bool
#source_cloud_updated_ : bool
#target_cloud_updated_ : bool
#corr_dist_threshold_ : double
#euclidean_fitness_epsilon_ : double
+getEuclideanFitnessEpsilon() : double
+getFitnessScore(double max_range) : double
+getFitnessScore(const std::vector& distances_a, const std::vector& distances_b) : double
+getMaxCorrespondenceDistance() : double
+getRANSACIterations() : double
+getRANSACOutlierRejectionThreshold() : double
+getTransformationEpsilon() : double
#inlier_threshold_ : double
#transformation_epsilon_ : double
+getMaximumIterations() : int
#max_iterations_ : int
#min_number_correspondences_ : int
#nr_iterations_ : int
#ransac_iterations_ : int
#reg_name_ : std::string
+getClassName() : std::string& {query}
#correspondence_rejectors_ : std::vector
+getCorrespondenceRejectors() : std::vector
+addCorrespondenceRejector(const CorrespondenceRejectorPtr& rejector) : void
+align(PointCloudSource& output) : void
+align(PointCloudSource& output, const Matrix4& guess) : void
+clearCorrespondenceRejectors() : void
#{abstract} computeTransformation(PointCloudSource& output, const Matrix4& guess) : void
+setCorrespondenceEstimation(const CorrespondenceEstimationPtr& ce) : void
+setEuclideanFitnessEpsilon(double epsilon) : void
+setInputSource(const PointCloudSourceConstPtr& cloud) : void
+setInputTarget(const PointCloudTargetConstPtr& cloud) : void
+setMaxCorrespondenceDistance(double distance_threshold) : void
+setMaximumIterations(int nr_iterations) : void
+setPointRepresentation(const PointRepresentationConstPtr& point_representation) : void
+setRANSACIterations(int ransac_iterations) : void
+setRANSACOutlierRejectionThreshold(double inlier_threshold) : void
+setSearchMethodSource(const KdTreeReciprocalPtr& tree, bool force_no_recompute) : void
+setSearchMethodTarget(const KdTreePtr& tree, bool force_no_recompute) : void
+setTransformationEpsilon(double epsilon) : void
+setTransformationEstimation(const TransformationEstimationPtr& te) : void
}
}

/' Inheritance relationships '/

namespace pcl {
PCLBase <|-- Registration
}

namespace pcl {
Registration <|-- NormalDistributionsTransform
}

/' Aggregation relationships '/

@enduml

Array member in struct will be parsed to its element type

The struct container_of_array is as following:

struct conatiner_of_array {
    int arr_of_nums[0];
    int num;
};

And the parsed puml file content will be like:

class conatiner_of_array {
	+arr_of_nums : int
	+num : int
}

The array type is ignored in puml result, which is incorrect.

Do not handle nest namespace correctly

Demo

namespace a::b::c {
  class A {
  public:
    void foo();
  };
}

namespace a::b {
  class B{
  public:
    void bar();
  };
}

Currently it generate:

@startuml
/' Objects '/
namespace a {
	namespace b {
		class B {
			+bar() : void
		}

		namespace c {
			class A {
				+foo() : void
			}
		}
	}
}

namespace a {
	namespace b {
		class B {
			+bar() : void
		}

		namespace c {
			class A {
				+foo() : void
			}
		}
	}
}
/' Inheritance relationships '/
/' Aggregation relationships '/
/' Nested objects '/
@enduml

As you can see, hpp2plantuml generate duplicate text. I'm using version 0.8.2.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.